summaryrefslogtreecommitdiffstats
path: root/toolkit/components/protobuf/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /toolkit/components/protobuf/src
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/protobuf/src')
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/any.cc82
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/any.h157
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/any.pb.cc368
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/any.pb.h384
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/any.proto158
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/any_lite.cc96
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/api.pb.cc1309
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/api.pb.h1437
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/api.proto208
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/arena.cc537
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/arena.h851
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/arena_impl.h686
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/arenastring.cc267
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/arenastring.h480
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/arenaz_sampler.cc177
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/arenaz_sampler.h207
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/descriptor.cc8340
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/descriptor.h2440
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/descriptor.pb.cc11351
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/descriptor.pb.h14821
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/descriptor.proto921
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/descriptor_database.cc1048
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/descriptor_database.h398
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/duration.pb.cc307
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/duration.pb.h278
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/duration.proto116
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/dynamic_message.cc826
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/dynamic_message.h227
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/empty.pb.cc130
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/empty.pb.h198
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/empty.proto51
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/endian.h198
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/explicitly_constructed.h97
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/extension_set.cc1967
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/extension_set.h1561
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/extension_set_heavy.cc440
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/extension_set_inl.h285
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/field_access_listener.h172
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/field_mask.pb.cc284
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/field_mask.pb.h317
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/field_mask.proto245
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/generated_enum_reflection.h100
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/generated_enum_util.cc95
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/generated_enum_util.h85
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/generated_message_bases.cc124
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/generated_message_bases.h87
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.cc3168
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.h354
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_decl.h312
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_full.cc53
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_impl.h553
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_lite.cc1859
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/generated_message_util.cc409
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/generated_message_util.h214
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/has_bits.h117
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/implicit_weak_message.cc72
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/implicit_weak_message.h213
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/inlined_string_field.cc118
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/inlined_string_field.h532
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/coded_stream.cc967
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/coded_stream.h1799
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.cc334
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.h205
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/io_win32.cc471
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/io_win32.h141
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/package_info.h53
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/printer.cc403
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/printer.h387
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/strtod.cc82
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/strtod.h55
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/tokenizer.cc1239
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/tokenizer.h442
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.cc55
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.h260
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc372
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h336
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc470
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h413
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/map.cc41
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/map.h1448
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/map_entry.h134
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/map_entry_lite.h563
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/map_field.cc654
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/map_field.h946
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/map_field_inl.h375
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/map_field_lite.h209
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/map_type_handler.h736
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/message.cc404
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/message.h1497
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/message_lite.cc603
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/message_lite.h591
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/metadata.h36
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/metadata_lite.h316
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/package_info.h66
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/parse_context.cc548
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/parse_context.h1025
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/port.h80
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/port_def.inc928
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/port_undef.inc160
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/reflection.h570
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/reflection_internal.h364
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/reflection_ops.cc459
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/reflection_ops.h92
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/repeated_field.cc71
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/repeated_field.h1219
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/repeated_ptr_field.cc152
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/repeated_ptr_field.h1970
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/service.cc45
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/service.h295
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/source_context.pb.cc297
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/source_context.pb.h282
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/source_context.proto48
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/string_member_robber.h38
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/struct.pb.cc1057
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/struct.pb.h1177
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/struct.proto95
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/bytestream.cc194
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/bytestream.h351
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/callback.h583
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/casts.h138
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/common.cc324
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/common.h196
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/hash.h114
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/int128.cc193
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/int128.h387
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/logging.h239
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/macros.h93
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/map_util.h769
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/mathutil.h162
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/mutex.h218
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/once.h55
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h138
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/port.h413
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/status.cc262
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/status.h196
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/status_macros.h89
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/statusor.cc48
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/statusor.h253
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/stl_util.h90
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/stringpiece.cc256
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/stringpiece.h402
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.cc175
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.h85
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/structurally_valid.cc617
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/strutil.cc2479
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/strutil.h950
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/substitute.cc136
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/substitute.h178
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/template_util.h138
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/time.cc365
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/stubs/time.h82
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/text_format.cc2746
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/text_format.h693
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/timestamp.pb.cc307
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/timestamp.pb.h278
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/timestamp.proto147
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/type.pb.cc2157
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/type.pb.h2571
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/type.proto187
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/unknown_field_set.cc350
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/unknown_field_set.h407
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/delimited_message_util.cc128
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/delimited_message_util.h109
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/field_comparator.cc210
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/field_comparator.h288
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/field_mask_util.cc720
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/field_mask_util.h263
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/constants.h101
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/datapiece.cc441
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/datapiece.h219
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/default_value_objectwriter.cc642
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/default_value_objectwriter.h332
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/error_listener.cc42
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/error_listener.h109
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/expecting_objectwriter.h250
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/field_mask_utility.cc218
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/field_mask_utility.h74
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/json_escaping.cc372
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/json_escaping.h98
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/json_objectwriter.cc190
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/json_objectwriter.h278
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/json_stream_parser.cc995
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/json_stream_parser.h350
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/location_tracker.h70
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/mock_error_listener.h68
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/object_location_tracker.h64
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/object_source.h85
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/object_writer.cc93
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/object_writer.h151
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/proto_writer.cc827
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/proto_writer.h389
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectsource.cc1114
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectsource.h329
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectwriter.cc1401
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectwriter.h453
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/structured_objectwriter.h121
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/type_info.cc182
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/type_info.h97
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/utility.cc416
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/internal/utility.h204
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/json_format.proto140
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/json_format_proto3.proto194
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/json_util.cc284
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/json_util.h204
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/message_differencer.cc2246
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/message_differencer.h980
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/package_info.h46
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/time_util.cc514
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/time_util.h314
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/type_resolver.h77
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/type_resolver_util.cc370
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/type_resolver_util.h58
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/wire_format.cc1768
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/wire_format.h414
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/wire_format_lite.cc818
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/wire_format_lite.h1908
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/wrappers.pb.cc1979
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/wrappers.pb.h1741
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/wrappers.proto123
219 files changed, 138844 insertions, 0 deletions
diff --git a/toolkit/components/protobuf/src/google/protobuf/any.cc b/toolkit/components/protobuf/src/google/protobuf/any.cc
new file mode 100644
index 0000000000..346fa19f17
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/any.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/any.h>
+
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/message.h>
+
+// Must be included last.
+#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(
+ GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix), arena);
+ return message.SerializeToString(value_->Mutable(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/toolkit/components/protobuf/src/google/protobuf/any.h b/toolkit/components/protobuf/src/google/protobuf/any.h
new file mode 100644
index 0000000000..92ea2bb2c7
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/any.h
@@ -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.
+
+#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>
+
+// Must be included last.
+#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/".
+
+std::string 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 a static method on the
+// generated message type: google::protobuf::Any::ParseAnyTypeUrl()
+bool ParseAnyTypeUrl(StringPiece type_url, std::string* 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, std::string* url_prefix,
+ std::string* 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/toolkit/components/protobuf/src/google/protobuf/any.pb.cc b/toolkit/components/protobuf/src/google/protobuf/any.pb.cc
new file mode 100644
index 0000000000..c02f9eb7f8
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/any.pb.cc
@@ -0,0 +1,368 @@
+// 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
+
+namespace _pb = ::PROTOBUF_NAMESPACE_ID;
+namespace _pbi = _pb::internal;
+
+#if defined(__llvm__)
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wuninitialized"
+#endif // __llvm__
+PROTOBUF_NAMESPACE_OPEN
+PROTOBUF_CONSTEXPR Any::Any(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.type_url_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.value_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_._any_metadata_)*/{&_impl_.type_url_, &_impl_.value_}} {}
+struct AnyDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR AnyDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~AnyDefaultTypeInternal() {}
+ union {
+ Any _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 AnyDefaultTypeInternal _Any_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fany_2eproto[1];
+static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto = nullptr;
+static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fany_2eproto = nullptr;
+
+const uint32_t 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, _impl_.type_url_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Any, _impl_.value_),
+};
+static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Any)},
+};
+
+static const ::_pb::Message* const file_default_instances[] = {
+ &::PROTOBUF_NAMESPACE_ID::_Any_default_instance_._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 ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fany_2eproto_once;
+const ::_pbi::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 ::_pbi::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_PRIORITY2 static ::_pbi::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 ::_pbi::GetAnyFieldDescriptors(
+ message, type_url_field, value_field);
+}
+bool Any::ParseAnyTypeUrl(
+ ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url,
+ std::string* full_type_name) {
+ return ::_pbi::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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Any)
+}
+Any::Any(const Any& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Any* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.type_url_){}
+ , decltype(_impl_.value_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_._any_metadata_)*/{&_impl_.type_url_, &_impl_.value_}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.type_url_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.type_url_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_type_url().empty()) {
+ _this->_impl_.type_url_.Set(from._internal_type_url(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_value().empty()) {
+ _this->_impl_.value_.Set(from._internal_value(),
+ _this->GetArenaForAllocation());
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Any)
+}
+
+inline void Any::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.type_url_){}
+ , decltype(_impl_.value_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_._any_metadata_)*/{&_impl_.type_url_, &_impl_.value_}
+ };
+ _impl_.type_url_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.type_url_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+Any::~Any() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Any)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Any::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.type_url_.Destroy();
+ _impl_.value_.Destroy();
+ _impl_._any_metadata_.~AnyMetadata();
+}
+
+void Any::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void Any::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Any)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.type_url_.ClearToEmpty();
+ _impl_.value_.ClearToEmpty();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Any::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Any.type_url"));
+ } 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 = ::_pbi::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)
+ uint32_t 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 = ::_pbi::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;
+
+ uint32_t 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, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Any::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Any::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Any::GetClassData() const { return &_class_data_; }
+
+
+void Any::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Any*>(&to_msg);
+ auto& from = static_cast<const Any&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (!from._internal_type_url().empty()) {
+ _this->_internal_set_type_url(from._internal_type_url());
+ }
+ if (!from._internal_value().empty()) {
+ _this->_internal_set_value(from._internal_value());
+ }
+ _this->_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(
+ &_impl_.type_url_, lhs_arena,
+ &other->_impl_.type_url_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.value_, lhs_arena,
+ &other->_impl_.value_, rhs_arena
+ );
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Any::GetMetadata() const {
+ return ::_pbi::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)
+#if defined(__llvm__)
+ #pragma clang diagnostic pop
+#endif // __llvm__
+#include <google/protobuf/port_undef.inc>
diff --git a/toolkit/components/protobuf/src/google/protobuf/any.pb.h b/toolkit/components/protobuf/src/google/protobuf/any.pb.h
new file mode 100644
index 0000000000..ac51c9bcac
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/any.pb.h
@@ -0,0 +1,384 @@
+// 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 < 3021000
+#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 3021006 < 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_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 uint32_t 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 PROTOBUF_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) {
+ GOOGLE_DCHECK_NE(&message, this);
+ return _impl_._any_metadata_.PackFrom(GetArena(), message);
+ }
+ bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message,
+ ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) {
+ GOOGLE_DCHECK_NE(&message, this);
+ return _impl_._any_metadata_.PackFrom(GetArena(), message, type_url_prefix);
+ }
+ bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const {
+ return _impl_._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 _impl_._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 _impl_._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 _impl_._any_metadata_.UnpackTo<T>(message);
+ }
+ template<typename T> bool Is() const {
+ return _impl_._any_metadata_.Is<T>();
+ }
+ static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url,
+ std::string* 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) {
+ Any::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& type_url() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_type_url(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_type_url();
+ PROTOBUF_NODISCARD std::string* release_type_url();
+ void set_allocated_type_url(std::string* type_url);
+ private:
+ const std::string& _internal_type_url() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_type_url(const std::string& value);
+ std::string* _internal_mutable_type_url();
+ public:
+
+ // bytes value = 2;
+ void clear_value();
+ const std::string& value() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_value(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_value();
+ PROTOBUF_NODISCARD std::string* release_value();
+ void set_allocated_value(std::string* value);
+ private:
+ const std::string& _internal_value() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_value(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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() {
+ _impl_.type_url_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.type_url_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Any.type_url)
+}
+inline std::string* Any::mutable_type_url() {
+ std::string* _s = _internal_mutable_type_url();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Any.type_url)
+ return _s;
+}
+inline const std::string& Any::_internal_type_url() const {
+ return _impl_.type_url_.Get();
+}
+inline void Any::_internal_set_type_url(const std::string& value) {
+
+ _impl_.type_url_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Any::_internal_mutable_type_url() {
+
+ return _impl_.type_url_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Any::release_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Any.type_url)
+ return _impl_.type_url_.Release();
+}
+inline void Any::set_allocated_type_url(std::string* type_url) {
+ if (type_url != nullptr) {
+
+ } else {
+
+ }
+ _impl_.type_url_.SetAllocated(type_url, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.type_url_.IsDefault()) {
+ _impl_.type_url_.Set("", 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() {
+ _impl_.value_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.value_.SetBytes(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Any.value)
+}
+inline std::string* Any::mutable_value() {
+ std::string* _s = _internal_mutable_value();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Any.value)
+ return _s;
+}
+inline const std::string& Any::_internal_value() const {
+ return _impl_.value_.Get();
+}
+inline void Any::_internal_set_value(const std::string& value) {
+
+ _impl_.value_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Any::_internal_mutable_value() {
+
+ return _impl_.value_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Any::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Any.value)
+ return _impl_.value_.Release();
+}
+inline void Any::set_allocated_value(std::string* value) {
+ if (value != nullptr) {
+
+ } else {
+
+ }
+ _impl_.value_.SetAllocated(value, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.value_.IsDefault()) {
+ _impl_.value_.Set("", 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/toolkit/components/protobuf/src/google/protobuf/any.proto b/toolkit/components/protobuf/src/google/protobuf/any.proto
new file mode 100644
index 0000000000..e2c2042fdc
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/any_lite.cc b/toolkit/components/protobuf/src/google/protobuf/any_lite.cc
new file mode 100644
index 0000000000..f283a31b0c
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/any_lite.cc
@@ -0,0 +1,96 @@
+// 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/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/any.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_util.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+std::string 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(GetTypeUrl(type_name, type_url_prefix), arena);
+ return message.SerializeToString(value_->Mutable(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, std::string* url_prefix,
+ std::string* full_type_name) {
+ size_t pos = type_url.find_last_of('/');
+ if (pos == std::string::npos || pos + 1 == type_url.size()) {
+ return false;
+ }
+ if (url_prefix) {
+ *url_prefix = std::string(type_url.substr(0, pos + 1));
+ }
+ *full_type_name = std::string(type_url.substr(pos + 1));
+ return true;
+}
+
+bool ParseAnyTypeUrl(StringPiece type_url, std::string* full_type_name) {
+ return ParseAnyTypeUrl(type_url, nullptr, full_type_name);
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/toolkit/components/protobuf/src/google/protobuf/api.pb.cc b/toolkit/components/protobuf/src/google/protobuf/api.pb.cc
new file mode 100644
index 0000000000..24b60497cd
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/api.pb.cc
@@ -0,0 +1,1309 @@
+// 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
+
+namespace _pb = ::PROTOBUF_NAMESPACE_ID;
+namespace _pbi = _pb::internal;
+
+PROTOBUF_NAMESPACE_OPEN
+PROTOBUF_CONSTEXPR Api::Api(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.methods_)*/{}
+ , /*decltype(_impl_.options_)*/{}
+ , /*decltype(_impl_.mixins_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.version_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.source_context_)*/nullptr
+ , /*decltype(_impl_.syntax_)*/0
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct ApiDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR ApiDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~ApiDefaultTypeInternal() {}
+ union {
+ Api _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ApiDefaultTypeInternal _Api_default_instance_;
+PROTOBUF_CONSTEXPR Method::Method(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.options_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.request_type_url_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.response_type_url_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.request_streaming_)*/false
+ , /*decltype(_impl_.response_streaming_)*/false
+ , /*decltype(_impl_.syntax_)*/0
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct MethodDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR MethodDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~MethodDefaultTypeInternal() {}
+ union {
+ Method _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MethodDefaultTypeInternal _Method_default_instance_;
+PROTOBUF_CONSTEXPR Mixin::Mixin(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.root_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct MixinDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR MixinDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~MixinDefaultTypeInternal() {}
+ union {
+ Mixin _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MixinDefaultTypeInternal _Mixin_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fapi_2eproto[3];
+static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr;
+static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr;
+
+const uint32_t 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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _impl_.methods_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _impl_.options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _impl_.version_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _impl_.source_context_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _impl_.mixins_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _impl_.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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _impl_.request_type_url_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _impl_.request_streaming_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _impl_.response_type_url_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _impl_.response_streaming_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _impl_.options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _impl_.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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, _impl_.root_),
+};
+static const ::_pbi::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 const ::_pb::Message* const file_default_instances[] = {
+ &::PROTOBUF_NAMESPACE_ID::_Api_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_Method_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_Mixin_default_instance_._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 ::_pbi::DescriptorTable* const descriptor_table_google_2fprotobuf_2fapi_2eproto_deps[2] = {
+ &::descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto,
+ &::descriptor_table_google_2fprotobuf_2ftype_2eproto,
+};
+static ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fapi_2eproto_once;
+const ::_pbi::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 ::_pbi::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_PRIORITY2 static ::_pbi::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->_impl_.source_context_;
+}
+void Api::clear_options() {
+ _impl_.options_.Clear();
+}
+void Api::clear_source_context() {
+ if (GetArenaForAllocation() == nullptr && _impl_.source_context_ != nullptr) {
+ delete _impl_.source_context_;
+ }
+ _impl_.source_context_ = nullptr;
+}
+Api::Api(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Api)
+}
+Api::Api(const Api& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Api* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.methods_){from._impl_.methods_}
+ , decltype(_impl_.options_){from._impl_.options_}
+ , decltype(_impl_.mixins_){from._impl_.mixins_}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.version_){}
+ , decltype(_impl_.source_context_){nullptr}
+ , decltype(_impl_.syntax_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.version_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.version_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_version().empty()) {
+ _this->_impl_.version_.Set(from._internal_version(),
+ _this->GetArenaForAllocation());
+ }
+ if (from._internal_has_source_context()) {
+ _this->_impl_.source_context_ = new ::PROTOBUF_NAMESPACE_ID::SourceContext(*from._impl_.source_context_);
+ }
+ _this->_impl_.syntax_ = from._impl_.syntax_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Api)
+}
+
+inline void Api::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.methods_){arena}
+ , decltype(_impl_.options_){arena}
+ , decltype(_impl_.mixins_){arena}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.version_){}
+ , decltype(_impl_.source_context_){nullptr}
+ , decltype(_impl_.syntax_){0}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.version_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.version_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+Api::~Api() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Api)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Api::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.methods_.~RepeatedPtrField();
+ _impl_.options_.~RepeatedPtrField();
+ _impl_.mixins_.~RepeatedPtrField();
+ _impl_.name_.Destroy();
+ _impl_.version_.Destroy();
+ if (this != internal_default_instance()) delete _impl_.source_context_;
+}
+
+void Api::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void Api::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Api)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.methods_.Clear();
+ _impl_.options_.Clear();
+ _impl_.mixins_.Clear();
+ _impl_.name_.ClearToEmpty();
+ _impl_.version_.ClearToEmpty();
+ if (GetArenaForAllocation() == nullptr && _impl_.source_context_ != nullptr) {
+ delete _impl_.source_context_;
+ }
+ _impl_.source_context_ = nullptr;
+ _impl_.syntax_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Api::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Api.name"));
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Api.version"));
+ } 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)) {
+ uint64_t 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)
+ uint32_t 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 i = 0,
+ n = static_cast<unsigned>(this->_internal_methods_size()); i < n; i++) {
+ const auto& repfield = this->_internal_methods(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // repeated .google.protobuf.Option options = 3;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_options_size()); i < n; i++) {
+ const auto& repfield = this->_internal_options(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(3, repfield, repfield.GetCachedSize(), 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(5, _Internal::source_context(this),
+ _Internal::source_context(this).GetCachedSize(), target, stream);
+ }
+
+ // repeated .google.protobuf.Mixin mixins = 6;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_mixins_size()); i < n; i++) {
+ const auto& repfield = this->_internal_mixins(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(6, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // .google.protobuf.Syntax syntax = 7;
+ if (this->_internal_syntax() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteEnumToArray(
+ 7, this->_internal_syntax(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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->_impl_.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->_impl_.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->_impl_.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(
+ *_impl_.source_context_);
+ }
+
+ // .google.protobuf.Syntax syntax = 7;
+ if (this->_internal_syntax() != 0) {
+ total_size += 1 +
+ ::_pbi::WireFormatLite::EnumSize(this->_internal_syntax());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Api::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Api::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Api::GetClassData() const { return &_class_data_; }
+
+
+void Api::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Api*>(&to_msg);
+ auto& from = static_cast<const Api&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.methods_.MergeFrom(from._impl_.methods_);
+ _this->_impl_.options_.MergeFrom(from._impl_.options_);
+ _this->_impl_.mixins_.MergeFrom(from._impl_.mixins_);
+ if (!from._internal_name().empty()) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (!from._internal_version().empty()) {
+ _this->_internal_set_version(from._internal_version());
+ }
+ if (from._internal_has_source_context()) {
+ _this->_internal_mutable_source_context()->::PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(
+ from._internal_source_context());
+ }
+ if (from._internal_syntax() != 0) {
+ _this->_internal_set_syntax(from._internal_syntax());
+ }
+ _this->_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_);
+ _impl_.methods_.InternalSwap(&other->_impl_.methods_);
+ _impl_.options_.InternalSwap(&other->_impl_.options_);
+ _impl_.mixins_.InternalSwap(&other->_impl_.mixins_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.version_, lhs_arena,
+ &other->_impl_.version_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(Api, _impl_.syntax_)
+ + sizeof(Api::_impl_.syntax_)
+ - PROTOBUF_FIELD_OFFSET(Api, _impl_.source_context_)>(
+ reinterpret_cast<char*>(&_impl_.source_context_),
+ reinterpret_cast<char*>(&other->_impl_.source_context_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Api::GetMetadata() const {
+ return ::_pbi::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() {
+ _impl_.options_.Clear();
+}
+Method::Method(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Method)
+}
+Method::Method(const Method& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Method* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.options_){from._impl_.options_}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.request_type_url_){}
+ , decltype(_impl_.response_type_url_){}
+ , decltype(_impl_.request_streaming_){}
+ , decltype(_impl_.response_streaming_){}
+ , decltype(_impl_.syntax_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.request_type_url_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.request_type_url_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_request_type_url().empty()) {
+ _this->_impl_.request_type_url_.Set(from._internal_request_type_url(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.response_type_url_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.response_type_url_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_response_type_url().empty()) {
+ _this->_impl_.response_type_url_.Set(from._internal_response_type_url(),
+ _this->GetArenaForAllocation());
+ }
+ ::memcpy(&_impl_.request_streaming_, &from._impl_.request_streaming_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.syntax_) -
+ reinterpret_cast<char*>(&_impl_.request_streaming_)) + sizeof(_impl_.syntax_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Method)
+}
+
+inline void Method::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.options_){arena}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.request_type_url_){}
+ , decltype(_impl_.response_type_url_){}
+ , decltype(_impl_.request_streaming_){false}
+ , decltype(_impl_.response_streaming_){false}
+ , decltype(_impl_.syntax_){0}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.request_type_url_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.request_type_url_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.response_type_url_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.response_type_url_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+Method::~Method() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Method)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Method::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.options_.~RepeatedPtrField();
+ _impl_.name_.Destroy();
+ _impl_.request_type_url_.Destroy();
+ _impl_.response_type_url_.Destroy();
+}
+
+void Method::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void Method::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Method)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.options_.Clear();
+ _impl_.name_.ClearToEmpty();
+ _impl_.request_type_url_.ClearToEmpty();
+ _impl_.response_type_url_.ClearToEmpty();
+ ::memset(&_impl_.request_streaming_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.syntax_) -
+ reinterpret_cast<char*>(&_impl_.request_streaming_)) + sizeof(_impl_.syntax_));
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Method::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Method.name"));
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Method.request_type_url"));
+ } else
+ goto handle_unusual;
+ continue;
+ // bool request_streaming = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
+ _impl_.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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Method.response_type_url"));
+ } else
+ goto handle_unusual;
+ continue;
+ // bool response_streaming = 5;
+ case 5:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) {
+ _impl_.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)) {
+ uint64_t 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)
+ uint32_t 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 = ::_pbi::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 = ::_pbi::WireFormatLite::WriteBoolToArray(5, this->_internal_response_streaming(), target);
+ }
+
+ // repeated .google.protobuf.Option options = 6;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_options_size()); i < n; i++) {
+ const auto& repfield = this->_internal_options(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(6, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // .google.protobuf.Syntax syntax = 7;
+ if (this->_internal_syntax() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteEnumToArray(
+ 7, this->_internal_syntax(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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->_impl_.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 +
+ ::_pbi::WireFormatLite::EnumSize(this->_internal_syntax());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Method::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Method::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Method::GetClassData() const { return &_class_data_; }
+
+
+void Method::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Method*>(&to_msg);
+ auto& from = static_cast<const Method&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.options_.MergeFrom(from._impl_.options_);
+ if (!from._internal_name().empty()) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (!from._internal_request_type_url().empty()) {
+ _this->_internal_set_request_type_url(from._internal_request_type_url());
+ }
+ if (!from._internal_response_type_url().empty()) {
+ _this->_internal_set_response_type_url(from._internal_response_type_url());
+ }
+ if (from._internal_request_streaming() != 0) {
+ _this->_internal_set_request_streaming(from._internal_request_streaming());
+ }
+ if (from._internal_response_streaming() != 0) {
+ _this->_internal_set_response_streaming(from._internal_response_streaming());
+ }
+ if (from._internal_syntax() != 0) {
+ _this->_internal_set_syntax(from._internal_syntax());
+ }
+ _this->_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_);
+ _impl_.options_.InternalSwap(&other->_impl_.options_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.request_type_url_, lhs_arena,
+ &other->_impl_.request_type_url_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.response_type_url_, lhs_arena,
+ &other->_impl_.response_type_url_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(Method, _impl_.syntax_)
+ + sizeof(Method::_impl_.syntax_)
+ - PROTOBUF_FIELD_OFFSET(Method, _impl_.request_streaming_)>(
+ reinterpret_cast<char*>(&_impl_.request_streaming_),
+ reinterpret_cast<char*>(&other->_impl_.request_streaming_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Method::GetMetadata() const {
+ return ::_pbi::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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Mixin)
+}
+Mixin::Mixin(const Mixin& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Mixin* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.name_){}
+ , decltype(_impl_.root_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.root_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.root_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_root().empty()) {
+ _this->_impl_.root_.Set(from._internal_root(),
+ _this->GetArenaForAllocation());
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin)
+}
+
+inline void Mixin::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.name_){}
+ , decltype(_impl_.root_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.root_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.root_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+Mixin::~Mixin() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Mixin)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Mixin::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.name_.Destroy();
+ _impl_.root_.Destroy();
+}
+
+void Mixin::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void Mixin::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Mixin)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.name_.ClearToEmpty();
+ _impl_.root_.ClearToEmpty();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Mixin::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Mixin.name"));
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Mixin.root"));
+ } 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)
+ uint32_t 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 = ::_pbi::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;
+
+ uint32_t 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, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Mixin::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Mixin::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Mixin::GetClassData() const { return &_class_data_; }
+
+
+void Mixin::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Mixin*>(&to_msg);
+ auto& from = static_cast<const Mixin&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (!from._internal_name().empty()) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (!from._internal_root().empty()) {
+ _this->_internal_set_root(from._internal_root());
+ }
+ _this->_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(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.root_, lhs_arena,
+ &other->_impl_.root_, rhs_arena
+ );
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Mixin::GetMetadata() const {
+ return ::_pbi::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/toolkit/components/protobuf/src/google/protobuf/api.pb.h b/toolkit/components/protobuf/src/google/protobuf/api.pb.h
new file mode 100644
index 0000000000..348bac8882
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/api.pb.h
@@ -0,0 +1,1437 @@
+// 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 < 3021000
+#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 3021006 < 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_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 uint32_t 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 PROTOBUF_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) {
+ Api::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _internal_mutable_name();
+ public:
+
+ // string version = 4;
+ void clear_version();
+ const std::string& version() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_version(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_version();
+ PROTOBUF_NODISCARD std::string* release_version();
+ void set_allocated_version(std::string* version);
+ private:
+ const std::string& _internal_version() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_version(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ Method::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _internal_mutable_name();
+ public:
+
+ // string request_type_url = 2;
+ void clear_request_type_url();
+ const std::string& request_type_url() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_request_type_url(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_request_type_url();
+ PROTOBUF_NODISCARD std::string* release_request_type_url();
+ void set_allocated_request_type_url(std::string* request_type_url);
+ private:
+ const std::string& _internal_request_type_url() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_request_type_url(const std::string& value);
+ std::string* _internal_mutable_request_type_url();
+ public:
+
+ // string response_type_url = 4;
+ void clear_response_type_url();
+ const std::string& response_type_url() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_response_type_url(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_response_type_url();
+ PROTOBUF_NODISCARD std::string* release_response_type_url();
+ void set_allocated_response_type_url(std::string* response_type_url);
+ private:
+ const std::string& _internal_response_type_url() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_response_type_url(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ Mixin::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _internal_mutable_name();
+ public:
+
+ // string root = 2;
+ void clear_root();
+ const std::string& root() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_root(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_root();
+ PROTOBUF_NODISCARD std::string* release_root();
+ void set_allocated_root(std::string* root);
+ private:
+ const std::string& _internal_root() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_root(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr root_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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() {
+ _impl_.name_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Api.name)
+}
+inline std::string* Api::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Api.name)
+ return _s;
+}
+inline const std::string& Api::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void Api::_internal_set_name(const std::string& value) {
+
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Api::_internal_mutable_name() {
+
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Api::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Api.name)
+ return _impl_.name_.Release();
+}
+inline void Api::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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 _impl_.methods_.size();
+}
+inline int Api::methods_size() const {
+ return _internal_methods_size();
+}
+inline void Api::clear_methods() {
+ _impl_.methods_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Method* Api::mutable_methods(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Api.methods)
+ return _impl_.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 &_impl_.methods_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Method& Api::_internal_methods(int index) const {
+ return _impl_.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 _impl_.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 _impl_.methods_;
+}
+
+// repeated .google.protobuf.Option options = 3;
+inline int Api::_internal_options_size() const {
+ return _impl_.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 _impl_.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 &_impl_.options_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Api::_internal_options(int index) const {
+ return _impl_.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 _impl_.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 _impl_.options_;
+}
+
+// string version = 4;
+inline void Api::clear_version() {
+ _impl_.version_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.version_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Api.version)
+}
+inline std::string* Api::mutable_version() {
+ std::string* _s = _internal_mutable_version();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Api.version)
+ return _s;
+}
+inline const std::string& Api::_internal_version() const {
+ return _impl_.version_.Get();
+}
+inline void Api::_internal_set_version(const std::string& value) {
+
+ _impl_.version_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Api::_internal_mutable_version() {
+
+ return _impl_.version_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Api::release_version() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Api.version)
+ return _impl_.version_.Release();
+}
+inline void Api::set_allocated_version(std::string* version) {
+ if (version != nullptr) {
+
+ } else {
+
+ }
+ _impl_.version_.SetAllocated(version, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.version_.IsDefault()) {
+ _impl_.version_.Set("", 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() && _impl_.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 = _impl_.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*>(_impl_.source_context_);
+ }
+ _impl_.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 = _impl_.source_context_;
+ _impl_.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 = _impl_.source_context_;
+ _impl_.source_context_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::_internal_mutable_source_context() {
+
+ if (_impl_.source_context_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(GetArenaForAllocation());
+ _impl_.source_context_ = p;
+ }
+ return _impl_.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*>(_impl_.source_context_);
+ }
+ if (source_context) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(
+ 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 {
+
+ }
+ _impl_.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 _impl_.mixins_.size();
+}
+inline int Api::mixins_size() const {
+ return _internal_mixins_size();
+}
+inline void Api::clear_mixins() {
+ _impl_.mixins_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Mixin* Api::mutable_mixins(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Api.mixins)
+ return _impl_.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 &_impl_.mixins_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Mixin& Api::_internal_mixins(int index) const {
+ return _impl_.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 _impl_.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 _impl_.mixins_;
+}
+
+// .google.protobuf.Syntax syntax = 7;
+inline void Api::clear_syntax() {
+ _impl_.syntax_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Syntax Api::_internal_syntax() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(_impl_.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) {
+
+ _impl_.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() {
+ _impl_.name_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Method.name)
+}
+inline std::string* Method::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Method.name)
+ return _s;
+}
+inline const std::string& Method::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void Method::_internal_set_name(const std::string& value) {
+
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Method::_internal_mutable_name() {
+
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Method::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Method.name)
+ return _impl_.name_.Release();
+}
+inline void Method::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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() {
+ _impl_.request_type_url_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.request_type_url_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Method.request_type_url)
+}
+inline std::string* Method::mutable_request_type_url() {
+ std::string* _s = _internal_mutable_request_type_url();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Method.request_type_url)
+ return _s;
+}
+inline const std::string& Method::_internal_request_type_url() const {
+ return _impl_.request_type_url_.Get();
+}
+inline void Method::_internal_set_request_type_url(const std::string& value) {
+
+ _impl_.request_type_url_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Method::_internal_mutable_request_type_url() {
+
+ return _impl_.request_type_url_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Method::release_request_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Method.request_type_url)
+ return _impl_.request_type_url_.Release();
+}
+inline void Method::set_allocated_request_type_url(std::string* request_type_url) {
+ if (request_type_url != nullptr) {
+
+ } else {
+
+ }
+ _impl_.request_type_url_.SetAllocated(request_type_url, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.request_type_url_.IsDefault()) {
+ _impl_.request_type_url_.Set("", 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() {
+ _impl_.request_streaming_ = false;
+}
+inline bool Method::_internal_request_streaming() const {
+ return _impl_.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) {
+
+ _impl_.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() {
+ _impl_.response_type_url_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.response_type_url_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Method.response_type_url)
+}
+inline std::string* Method::mutable_response_type_url() {
+ std::string* _s = _internal_mutable_response_type_url();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Method.response_type_url)
+ return _s;
+}
+inline const std::string& Method::_internal_response_type_url() const {
+ return _impl_.response_type_url_.Get();
+}
+inline void Method::_internal_set_response_type_url(const std::string& value) {
+
+ _impl_.response_type_url_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Method::_internal_mutable_response_type_url() {
+
+ return _impl_.response_type_url_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Method::release_response_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Method.response_type_url)
+ return _impl_.response_type_url_.Release();
+}
+inline void Method::set_allocated_response_type_url(std::string* response_type_url) {
+ if (response_type_url != nullptr) {
+
+ } else {
+
+ }
+ _impl_.response_type_url_.SetAllocated(response_type_url, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.response_type_url_.IsDefault()) {
+ _impl_.response_type_url_.Set("", 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() {
+ _impl_.response_streaming_ = false;
+}
+inline bool Method::_internal_response_streaming() const {
+ return _impl_.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) {
+
+ _impl_.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 _impl_.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 _impl_.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 &_impl_.options_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Method::_internal_options(int index) const {
+ return _impl_.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 _impl_.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 _impl_.options_;
+}
+
+// .google.protobuf.Syntax syntax = 7;
+inline void Method::clear_syntax() {
+ _impl_.syntax_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Syntax Method::_internal_syntax() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(_impl_.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) {
+
+ _impl_.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() {
+ _impl_.name_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Mixin.name)
+}
+inline std::string* Mixin::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.name)
+ return _s;
+}
+inline const std::string& Mixin::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void Mixin::_internal_set_name(const std::string& value) {
+
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Mixin::_internal_mutable_name() {
+
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Mixin::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Mixin.name)
+ return _impl_.name_.Release();
+}
+inline void Mixin::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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() {
+ _impl_.root_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.root_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Mixin.root)
+}
+inline std::string* Mixin::mutable_root() {
+ std::string* _s = _internal_mutable_root();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.root)
+ return _s;
+}
+inline const std::string& Mixin::_internal_root() const {
+ return _impl_.root_.Get();
+}
+inline void Mixin::_internal_set_root(const std::string& value) {
+
+ _impl_.root_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Mixin::_internal_mutable_root() {
+
+ return _impl_.root_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Mixin::release_root() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Mixin.root)
+ return _impl_.root_.Release();
+}
+inline void Mixin::set_allocated_root(std::string* root) {
+ if (root != nullptr) {
+
+ } else {
+
+ }
+ _impl_.root_.SetAllocated(root, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.root_.IsDefault()) {
+ _impl_.root_.Set("", 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/toolkit/components/protobuf/src/google/protobuf/api.proto b/toolkit/components/protobuf/src/google/protobuf/api.proto
new file mode 100644
index 0000000000..3d598fc859
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/arena.cc b/toolkit/components/protobuf/src/google/protobuf/arena.cc
new file mode 100644
index 0000000000..6ba508a5f0
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/arena.cc
@@ -0,0 +1,537 @@
+// 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/arenaz_sampler.h>
+#include <google/protobuf/port.h>
+
+#include <google/protobuf/stubs/mutex.h>
+#ifdef ADDRESS_SANITIZER
+#include <sanitizer/asan_interface.h>
+#endif // ADDRESS_SANITIZER
+
+// Must be included last.
+#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 {
+ internal::SizedDelete(mem.ptr, mem.size);
+ }
+ *space_allocated_ += mem.size;
+ }
+
+ private:
+ void (*dealloc_)(void*, size_t);
+ size_t* space_allocated_;
+};
+
+SerialArena::SerialArena(Block* b, void* owner, ThreadSafeArenaStats* stats)
+ : space_allocated_(b->size) {
+ owner_ = owner;
+ head_ = b;
+ ptr_ = b->Pointer(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize);
+ limit_ = b->Pointer(b->size & static_cast<size_t>(-8));
+ arena_stats_ = stats;
+}
+
+SerialArena* SerialArena::New(Memory mem, void* owner,
+ ThreadSafeArenaStats* stats) {
+ GOOGLE_DCHECK_LE(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize, mem.size);
+ ThreadSafeArenaStats::RecordAllocateStats(
+ stats, /*requested=*/mem.size, /*allocated=*/mem.size, /*wasted=*/0);
+ auto b = new (mem.ptr) Block{nullptr, mem.size};
+ return new (b->Pointer(kBlockHeaderSize)) SerialArena(b, owner, stats);
+}
+
+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.
+ size_t used = ptr_ - head_->Pointer(kBlockHeaderSize);
+ size_t wasted = head_->size - used;
+ space_used_ += used;
+
+ // TODO(sbenza): Evaluate if pushing unused space into the cached blocks is a
+ // win. In preliminary testing showed increased memory savings as expected,
+ // but with a CPU regression. The regression might have been an artifact of
+ // the microbenchmark.
+
+ 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);
+ ThreadSafeArenaStats::RecordAllocateStats(arena_stats_, /*requested=*/n,
+ /*allocated=*/mem.size, wasted);
+ 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
+}
+
+uint64_t SerialArena::SpaceUsed() const {
+ uint64_t 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 uint64_t 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 uint64_t kDelta = 2;
+ constexpr uint64_t 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 uint64_t 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
+ arena_stats_ = Sample();
+}
+
+void ThreadSafeArena::SetInitialBlock(void* mem, size_t size) {
+ SerialArena* serial = SerialArena::New({mem, size}, &thread_cache(),
+ arena_stats_.MutableStats());
+ 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()) {
+#ifdef ADDRESS_SANITIZER
+ // Unpoison the initial block, now that it's going back to the user.
+ ASAN_UNPOISON_MEMORY_REGION(mem.ptr, mem.size);
+#endif // ADDRESS_SANITIZER
+ 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;
+}
+
+uint64_t 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);
+ arena_stats_.RecordReset();
+
+ 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());
+}
+
+uint64_t ThreadSafeArena::SpaceAllocated() const {
+ SerialArena* serial = threads_.load(std::memory_order_acquire);
+ uint64_t res = 0;
+ for (; serial; serial = serial->next()) {
+ res += serial->SpaceAllocated();
+ }
+ return res;
+}
+
+uint64_t ThreadSafeArena::SpaceUsed() const {
+ SerialArena* serial = threads_.load(std::memory_order_acquire);
+ uint64_t 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,
+ arena_stats_.MutableStats());
+
+ 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)
+void* Arena::AllocateAlignedWithHookForArray(size_t n,
+ const std::type_info* type) {
+ return impl_.AllocateAligned<internal::AllocationClient::kArray>(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/toolkit/components/protobuf/src/google/protobuf/arena.h b/toolkit/components/protobuf/src/google/protobuf/arena.h
new file mode 100644
index 0000000000..3b5f16c389
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/arena.h
@@ -0,0 +1,851 @@
+// 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>
+#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>
+
+// Must be included last.
+#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 ArenaTestPeer; // defined in arena_test_util.h
+class InternalMetadata; // defined in metadata_lite.h
+class LazyField; // defined in lazy_field.h
+class EpsCopyInputStream; // defined in parse_context.h
+class RepeatedPtrFieldBase; // defined in repeated_ptr_field.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 final {
+ 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)...);
+ }
+
+ // Allocates memory with the specific size and alignment.
+ void* AllocateAligned(size_t size, size_t align = 8) {
+ if (align <= 8) {
+ return AllocateAlignedNoHook(internal::AlignUpTo8(size));
+ } 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(size + align - 8), align);
+ }
+ }
+
+ // 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.
+ uint64_t 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.
+ uint64_t 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.
+ uint64_t 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 {
+ private:
+ // Provides access to protected GetOwningArena to generated messages.
+ static Arena* GetOwningArena(const T* p) { return p->GetOwningArena(); }
+
+ static void InternalSwap(T* a, T* b) { a->InternalSwap(b); }
+
+ 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;
+ };
+
+ // Provides access to protected GetOwningArena to generated messages. For
+ // internal use only.
+ template <typename T>
+ static Arena* InternalGetOwningArena(const T* p) {
+ return InternalHelper<T>::GetOwningArena(p);
+ }
+
+ // Provides access to protected GetArenaForAllocation to generated messages.
+ // For internal use only.
+ template <typename T>
+ static Arena* InternalGetArenaForAllocation(const T* p) {
+ return InternalHelper<T>::GetArenaForAllocationInternal(
+ p, std::is_convertible<T*, MessageLite*>());
+ }
+
+ // Creates message-owned arena. For internal use only.
+ static Arena* InternalCreateMessageOwnedArena() {
+ return new Arena(internal::MessageOwned{});
+ }
+
+ // Checks whether this arena is message-owned. For internal use only.
+ bool InternalIsMessageOwnedArena() { return IsMessageOwned(); }
+
+ // 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();
+ }
+
+ void ReturnArrayMemory(void* p, size_t size) {
+ impl_.ReturnArrayMemory(p, size);
+ }
+
+ 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*>(
+ AllocateAlignedWithHookForArray(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;
+ }
+
+ void* AllocateAlignedWithHookForArray(size_t n, size_t align,
+ const std::type_info* type) {
+ if (align <= 8) {
+ return AllocateAlignedWithHookForArray(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 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(
+ AllocateAlignedWithHookForArray(n + align - 8, type), 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 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(AllocateAlignedWithHook(n + align - 8, type),
+ align);
+ }
+ }
+
+ void* AllocateAlignedNoHook(size_t n);
+ void* AllocateAlignedWithHook(size_t n, const std::type_info* type);
+ void* AllocateAlignedWithHookForArray(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 class internal::InternalMetadata; // For user_arena().
+ friend class internal::LazyField; // For CreateMaybeMessage.
+ friend class internal::EpsCopyInputStream; // For parser performance
+ friend class MessageLite;
+ template <typename Key, typename T>
+ friend class Map;
+ template <typename>
+ friend class RepeatedField; // For ReturnArrayMemory
+ friend class internal::RepeatedPtrFieldBase; // For ReturnArrayMemory
+ friend struct internal::ArenaTestPeer;
+};
+
+// 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/toolkit/components/protobuf/src/google/protobuf/arena_impl.h b/toolkit/components/protobuf/src/google/protobuf/arena_impl.h
new file mode 100644
index 0000000000..76727688b5
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/arena_impl.h
@@ -0,0 +1,686 @@
+// 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>
+#include <google/protobuf/stubs/port.h>
+
+#ifdef ADDRESS_SANITIZER
+#include <sanitizer/asan_interface.h>
+#endif // ADDRESS_SANITIZER
+
+#include <google/protobuf/arenaz_sampler.h>
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// To prevent sharing cache lines between threads
+#ifdef __cpp_aligned_new
+enum { kCacheAlignment = 64 };
+#else
+enum { kCacheAlignment = alignof(max_align_t) }; // do the best we can
+#endif
+
+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 = uint64_t;
+
+// 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(uint64_t 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(uint64_t 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,
+ uint64_t 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_;
+};
+
+enum class AllocationClient { kDefault, kArray };
+
+// 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();
+ uint64_t SpaceAllocated() const {
+ return space_allocated_.load(std::memory_order_relaxed);
+ }
+ uint64_t SpaceUsed() const;
+
+ bool HasSpace(size_t n) const {
+ return n <= static_cast<size_t>(limit_ - ptr_);
+ }
+
+ // See comments on `cached_blocks_` member for details.
+ PROTOBUF_ALWAYS_INLINE void* TryAllocateFromCachedBlock(size_t size) {
+ if (PROTOBUF_PREDICT_FALSE(size < 16)) return nullptr;
+ // We round up to the next larger block in case the memory doesn't match
+ // the pattern we are looking for.
+ const size_t index = Bits::Log2FloorNonZero64(size - 1) - 3;
+
+ if (index >= cached_block_length_) return nullptr;
+ auto& cached_head = cached_blocks_[index];
+ if (cached_head == nullptr) return nullptr;
+
+ void* ret = cached_head;
+#ifdef ADDRESS_SANITIZER
+ ASAN_UNPOISON_MEMORY_REGION(ret, size);
+#endif // ADDRESS_SANITIZER
+ cached_head = cached_head->next;
+ return ret;
+ }
+
+ // In kArray mode we look through cached blocks.
+ // We do not do this by default because most non-array allocations will not
+ // have the right size and will fail to find an appropriate cached block.
+ //
+ // TODO(sbenza): Evaluate if we should use cached blocks for message types of
+ // the right size. We can statically know if the allocation size can benefit
+ // from it.
+ template <AllocationClient alloc_client = AllocationClient::kDefault>
+ 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 (alloc_client == AllocationClient::kArray) {
+ if (void* res = TryAllocateFromCachedBlock(n)) {
+ return res;
+ }
+ }
+
+ 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;
+ }
+
+ // See comments on `cached_blocks_` member for details.
+ void ReturnArrayMemory(void* p, size_t size) {
+ // We only need to check for 32-bit platforms.
+ // In 64-bit platforms the minimum allocation size from Repeated*Field will
+ // be 16 guaranteed.
+ if (sizeof(void*) < 8) {
+ if (PROTOBUF_PREDICT_FALSE(size < 16)) return;
+ } else {
+ GOOGLE_DCHECK(size >= 16);
+ }
+
+ // We round down to the next smaller block in case the memory doesn't match
+ // the pattern we are looking for. eg, someone might have called Reserve()
+ // on the repeated field.
+ const size_t index = Bits::Log2FloorNonZero64(size) - 4;
+
+ if (PROTOBUF_PREDICT_FALSE(index >= cached_block_length_)) {
+ // We can't put this object on the freelist so make this object the
+ // freelist. It is guaranteed it is larger than the one we have, and
+ // large enough to hold another allocation of `size`.
+ CachedBlock** new_list = static_cast<CachedBlock**>(p);
+ size_t new_size = size / sizeof(CachedBlock*);
+
+ std::copy(cached_blocks_, cached_blocks_ + cached_block_length_,
+ new_list);
+ std::fill(new_list + cached_block_length_, new_list + new_size, nullptr);
+ cached_blocks_ = new_list;
+ // Make the size fit in uint8_t. This is the power of two, so we don't
+ // need anything larger.
+ cached_block_length_ =
+ static_cast<uint8_t>(std::min(size_t{64}, new_size));
+
+ return;
+ }
+
+ auto& cached_head = cached_blocks_[index];
+ auto* new_node = static_cast<CachedBlock*>(p);
+ new_node->next = cached_head;
+ cached_head = new_node;
+#ifdef ADDRESS_SANITIZER
+ ASAN_POISON_MEMORY_REGION(p, size);
+#endif // ADDRESS_SANITIZER
+ }
+
+ 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,
+ ThreadSafeArenaStats* stats);
+ // 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_;
+ // Limiting address up to which memory can be allocated from the head block.
+ char* limit_;
+ // For holding sampling information. The pointer is owned by the
+ // ThreadSafeArena that holds this serial arena.
+ ThreadSafeArenaStats* arena_stats_;
+
+ // Repeated*Field and Arena play together to reduce memory consumption by
+ // reusing blocks. Currently, natural growth of the repeated field types makes
+ // them allocate blocks of size `8 + 2^N, N>=3`.
+ // When the repeated field grows returns the previous block and we put it in
+ // this free list.
+ // `cached_blocks_[i]` points to the free list for blocks of size `8+2^(i+3)`.
+ // The array of freelists is grown when needed in `ReturnArrayMemory()`.
+ struct CachedBlock {
+ // Simple linked list.
+ CachedBlock* next;
+ };
+ uint8_t cached_block_length_ = 0;
+ CachedBlock** cached_blocks_ = nullptr;
+
+ // Constructor is private as only New() should be used.
+ inline SerialArena(Block* b, void* owner, ThreadSafeArenaStats* stats);
+ 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();
+
+ uint64_t Reset();
+
+ uint64_t SpaceAllocated() const;
+ uint64_t SpaceUsed() const;
+
+ template <AllocationClient alloc_client = AllocationClient::kDefault>
+ 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<alloc_client>(n, AllocPolicy());
+ } else {
+ return AllocateAlignedFallback(n, type);
+ }
+ }
+
+ void ReturnArrayMemory(void* p, size_t size) {
+ SerialArena* arena;
+ if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) {
+ arena->ReturnArrayMemory(p, size);
+ }
+ }
+
+ // 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* arena;
+ if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() &&
+ GetSerialArenaFromThreadCache(&arena))) {
+ return arena->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().
+ uint64_t tag_and_id_ = 0;
+ // The LSB of tag_and_id_ indicates if the arena is message-owned.
+ enum : uint64_t { kMessageOwnedArena = 1 };
+
+ TaggedAllocationPolicyPtr alloc_policy_; // Tagged pointer to AllocPolicy.
+
+ static_assert(std::is_trivially_destructible<SerialArena>{},
+ "SerialArena needs to be trivially destructible.");
+ // 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 uint64_t 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 != nullptr && 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(kCacheAlignment) 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(nullptr) {}
+#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`.
+ uint64_t next_lifecycle_id;
+ // The ThreadCache is considered valid as long as this matches the
+ // lifecycle_id of the arena being used.
+ uint64_t 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(kCacheAlignment) 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
+
+ ThreadSafeArenaStatsHandle arena_stats_;
+
+ 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/toolkit/components/protobuf/src/google/protobuf/arenastring.cc b/toolkit/components/protobuf/src/google/protobuf/arenastring.cc
new file mode 100644
index 0000000000..af0c9df6bc
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/arenastring.cc
@@ -0,0 +1,267 @@
+// 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 <cstddef>
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/stubs/mutex.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/parse_context.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 {
+
+namespace {
+
+// TaggedStringPtr::Flags uses the lower 2 bits as tags.
+// Enforce that allocated data aligns to at least 4 bytes, and that
+// the alignment of the global const string value does as well.
+// The alignment guaranteed by `new std::string` depends on both:
+// - new align = __STDCPP_DEFAULT_NEW_ALIGNMENT__ / max_align_t
+// - alignof(std::string)
+#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
+constexpr size_t kNewAlign = __STDCPP_DEFAULT_NEW_ALIGNMENT__;
+#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
+constexpr size_t kNewAlign = alignof(::max_align_t);
+#else
+constexpr size_t kNewAlign = alignof(std::max_align_t);
+#endif
+constexpr size_t kStringAlign = alignof(std::string);
+
+static_assert((kStringAlign > kNewAlign ? kStringAlign : kNewAlign) >= 4, "");
+static_assert(alignof(ExplicitlyConstructedArenaString) >= 4, "");
+
+} // namespace
+
+const std::string& LazyString::Init() const {
+ static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED};
+ mu.Lock();
+ const std::string* res = inited_.load(std::memory_order_acquire);
+ if (res == nullptr) {
+ auto init_value = init_value_;
+ res = ::new (static_cast<void*>(string_buf_))
+ std::string(init_value.ptr, init_value.size);
+ inited_.store(res, std::memory_order_release);
+ }
+ mu.Unlock();
+ return *res;
+}
+
+namespace {
+
+
+#if defined(NDEBUG) || !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL
+
+class ScopedCheckPtrInvariants {
+ public:
+ explicit ScopedCheckPtrInvariants(const TaggedStringPtr*) {}
+};
+
+#endif // NDEBUG || !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL
+
+// Creates a heap allocated std::string value.
+inline TaggedStringPtr CreateString(ConstStringParam value) {
+ TaggedStringPtr res;
+ res.SetAllocated(new std::string(value.data(), value.length()));
+ return res;
+}
+
+#if !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL
+
+// Creates an arena allocated std::string value.
+TaggedStringPtr CreateArenaString(Arena& arena, ConstStringParam s) {
+ TaggedStringPtr res;
+ res.SetMutableArena(Arena::Create<std::string>(&arena, s.data(), s.length()));
+ return res;
+}
+
+#endif // !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL
+
+} // namespace
+
+void ArenaStringPtr::Set(ConstStringParam value, Arena* arena) {
+ ScopedCheckPtrInvariants check(&tagged_ptr_);
+ if (IsDefault()) {
+ // If we're not on an arena, skip straight to a true string to avoid
+ // possible copy cost later.
+ tagged_ptr_ = arena != nullptr ? CreateArenaString(*arena, value)
+ : CreateString(value);
+ } else {
+ UnsafeMutablePointer()->assign(value.data(), value.length());
+ }
+}
+
+void ArenaStringPtr::Set(std::string&& value, Arena* arena) {
+ ScopedCheckPtrInvariants check(&tagged_ptr_);
+ if (IsDefault()) {
+ NewString(arena, std::move(value));
+ } else if (IsFixedSizeArena()) {
+ std::string* current = tagged_ptr_.Get();
+ auto* s = new (current) std::string(std::move(value));
+ arena->OwnDestructor(s);
+ tagged_ptr_.SetMutableArena(s);
+ } else /* !IsFixedSizeArena() */ {
+ *UnsafeMutablePointer() = std::move(value);
+ }
+}
+
+std::string* ArenaStringPtr::Mutable(Arena* arena) {
+ ScopedCheckPtrInvariants check(&tagged_ptr_);
+ if (tagged_ptr_.IsMutable()) {
+ return tagged_ptr_.Get();
+ } else {
+ return MutableSlow(arena);
+ }
+}
+
+std::string* ArenaStringPtr::Mutable(const LazyString& default_value,
+ Arena* arena) {
+ ScopedCheckPtrInvariants check(&tagged_ptr_);
+ if (tagged_ptr_.IsMutable()) {
+ return tagged_ptr_.Get();
+ } else {
+ return MutableSlow(arena, default_value);
+ }
+}
+
+std::string* ArenaStringPtr::MutableNoCopy(Arena* arena) {
+ ScopedCheckPtrInvariants check(&tagged_ptr_);
+ if (tagged_ptr_.IsMutable()) {
+ return tagged_ptr_.Get();
+ } else {
+ GOOGLE_DCHECK(IsDefault());
+ // Allocate empty. The contents are not relevant.
+ return NewString(arena);
+ }
+}
+
+template <typename... Lazy>
+std::string* ArenaStringPtr::MutableSlow(::google::protobuf::Arena* arena,
+ const Lazy&... lazy_default) {
+ GOOGLE_DCHECK(IsDefault());
+
+ // For empty defaults, this ends up calling the default constructor which is
+ // more efficient than a copy construction from
+ // GetEmptyStringAlreadyInited().
+ return NewString(arena, lazy_default.get()...);
+}
+
+std::string* ArenaStringPtr::Release() {
+ ScopedCheckPtrInvariants check(&tagged_ptr_);
+ if (IsDefault()) return nullptr;
+
+ std::string* released = tagged_ptr_.Get();
+ if (tagged_ptr_.IsArena()) {
+ released = tagged_ptr_.IsMutable() ? new std::string(std::move(*released))
+ : new std::string(*released);
+ }
+ InitDefault();
+ return released;
+}
+
+void ArenaStringPtr::SetAllocated(std::string* value, Arena* arena) {
+ ScopedCheckPtrInvariants check(&tagged_ptr_);
+ // Release what we have first.
+ Destroy();
+
+ if (value == nullptr) {
+ InitDefault();
+ } else {
+#ifndef NDEBUG
+ // 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.
+ std::string* new_value = new std::string(std::move(*value));
+ delete value;
+ value = new_value;
+#endif // !NDEBUG
+ InitAllocated(value, arena);
+ }
+}
+
+void ArenaStringPtr::Destroy() {
+ delete tagged_ptr_.GetIfAllocated();
+}
+
+void ArenaStringPtr::ClearToEmpty() {
+ ScopedCheckPtrInvariants check(&tagged_ptr_);
+ if (IsDefault()) {
+ // Already set to default -- do nothing.
+ } else {
+ // Unconditionally mask away the tag.
+ //
+ // UpdateArenaString uses assign when capacity is larger than the new
+ // value, which is trivially true in the donated string case.
+ // const_cast<std::string*>(PtrValue<std::string>())->clear();
+ tagged_ptr_.Get()->clear();
+ }
+}
+
+void ArenaStringPtr::ClearToDefault(const LazyString& default_value,
+ ::google::protobuf::Arena* arena) {
+ ScopedCheckPtrInvariants check(&tagged_ptr_);
+ (void)arena;
+ if (IsDefault()) {
+ // Already set to default -- do nothing.
+ } else {
+ UnsafeMutablePointer()->assign(default_value.get());
+ }
+}
+
+const char* EpsCopyInputStream::ReadArenaString(const char* ptr,
+ ArenaStringPtr* s,
+ Arena* arena) {
+ ScopedCheckPtrInvariants check(&s->tagged_ptr_);
+ GOOGLE_DCHECK(arena != nullptr);
+
+ int size = ReadSize(&ptr);
+ if (!ptr) return nullptr;
+
+ auto* str = s->NewString(arena);
+ ptr = ReadString(ptr, size, str);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ return ptr;
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
diff --git a/toolkit/components/protobuf/src/google/protobuf/arenastring.h b/toolkit/components/protobuf/src/google/protobuf/arenastring.h
new file mode 100644
index 0000000000..6bc8395f23
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/arenastring.h
@@ -0,0 +1,480 @@
+// 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 <algorithm>
+#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/explicitly_constructed.h>
+
+// must be last:
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+
+namespace google {
+namespace protobuf {
+namespace internal {
+class EpsCopyInputStream;
+
+class SwapFieldHelper;
+
+// Declared in message_lite.h
+PROTOBUF_EXPORT extern ExplicitlyConstructedArenaString
+ fixed_address_empty_string;
+
+// 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 std::string to save on
+ // space. We don't need the string array after Init() is done.
+ union {
+ mutable InitValue init_value_;
+ alignas(std::string) mutable char string_buf_[sizeof(std::string)];
+ };
+ mutable std::atomic<const std::string*> inited_;
+
+ const std::string& 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 std::string& Init() const;
+};
+
+class TaggedStringPtr {
+ public:
+ // Bit flags qualifying string properties. We can use 2 bits as
+ // ptr_ is guaranteed and enforced to be aligned on 4 byte boundaries.
+ enum Flags {
+ kArenaBit = 0x1, // ptr is arena allocated
+ kMutableBit = 0x2, // ptr contents are fully mutable
+ kMask = 0x3 // Bit mask
+ };
+
+ // Composed logical types
+ enum Type {
+ // Default strings are immutable and never owned.
+ kDefault = 0,
+
+ // Allocated strings are mutable and (as the name implies) owned.
+ // A heap allocated string must be deleted.
+ kAllocated = kMutableBit,
+
+ // Mutable arena strings are strings where the string instance is owned
+ // by the arena, but the string contents itself are owned by the string
+ // instance. Mutable arena string instances need to be destroyed which is
+ // typically done through a cleanup action added to the arena owning it.
+ kMutableArena = kArenaBit | kMutableBit,
+
+ // Fixed size arena strings are strings where both the string instance and
+ // the string contents are fully owned by the arena. Fixed size arena
+ // strings are a platform and c++ library specific customization. Fixed
+ // size arena strings are immutable, with the exception of custom internal
+ // updates to the content that fit inside the existing capacity.
+ // Fixed size arena strings must never be deleted or destroyed.
+ kFixedSizeArena = kArenaBit,
+ };
+
+ TaggedStringPtr() = default;
+ explicit constexpr TaggedStringPtr(ExplicitlyConstructedArenaString* ptr)
+ : ptr_(ptr) {}
+
+ // Sets the value to `p`, tagging the value as being a 'default' value.
+ // See documentation for kDefault for more info.
+ inline const std::string* SetDefault(const std::string* p) {
+ return TagAs(kDefault, const_cast<std::string*>(p));
+ }
+
+ // Sets the value to `p`, tagging the value as a heap allocated value.
+ // Allocated strings are mutable and (as the name implies) owned.
+ // `p` must not be null
+ inline std::string* SetAllocated(std::string* p) {
+ return TagAs(kAllocated, p);
+ }
+
+ // Sets the value to `p`, tagging the value as a fixed size arena string.
+ // See documentation for kFixedSizeArena for more info.
+ // `p` must not be null
+ inline std::string* SetFixedSizeArena(std::string* p) {
+ return TagAs(kFixedSizeArena, p);
+ }
+
+ // Sets the value to `p`, tagging the value as a mutable arena string.
+ // See documentation for kMutableArena for more info.
+ // `p` must not be null
+ inline std::string* SetMutableArena(std::string* p) {
+ return TagAs(kMutableArena, p);
+ }
+
+ // Returns true if the contents of the current string are fully mutable.
+ inline bool IsMutable() const { return as_int() & kMutableBit; }
+
+ // Returns true if the current string is an immutable default value.
+ inline bool IsDefault() const { return (as_int() & kMask) == kDefault; }
+
+ // If the current string is a heap-allocated mutable value, returns a pointer
+ // to it. Returns nullptr otherwise.
+ inline std::string *GetIfAllocated() const {
+ auto allocated = as_int() ^ kAllocated;
+ if (allocated & kMask) return nullptr;
+
+ auto ptr = reinterpret_cast<std::string*>(allocated);
+ PROTOBUF_ASSUME(ptr != nullptr);
+ return ptr;
+ }
+
+ // Returns true if the current string is an arena allocated value.
+ // This means it's either a mutable or fixed size arena string.
+ inline bool IsArena() const { return as_int() & kArenaBit; }
+
+ // Returns true if the current string is a fixed size arena allocated value.
+ inline bool IsFixedSizeArena() const {
+ return (as_int() & kMask) == kFixedSizeArena;
+ }
+
+ // Returns the contained string pointer.
+ inline std::string* Get() const {
+ return reinterpret_cast<std::string*>(as_int() & ~kMask);
+ }
+
+ // Returns true if the contained pointer is null, indicating some error.
+ // The Null value is only used during parsing for temporary values.
+ // A persisted ArenaStringPtr value is never null.
+ inline bool IsNull() { return ptr_ == nullptr; }
+
+ private:
+ static inline void assert_aligned(const void* p) {
+ GOOGLE_DCHECK_EQ(reinterpret_cast<uintptr_t>(p) & kMask, 0UL);
+ }
+
+ inline std::string* TagAs(Type type, std::string* p) {
+ GOOGLE_DCHECK(p != nullptr);
+ assert_aligned(p);
+ ptr_ = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(p) | type);
+ return p;
+ }
+
+ uintptr_t as_int() const { return reinterpret_cast<uintptr_t>(ptr_); }
+ void* ptr_;
+};
+
+static_assert(std::is_trivial<TaggedStringPtr>::value,
+ "TaggedStringPtr must be trivial");
+
+// This class encapsulates a pointer to a std::string with or without arena
+// owned contents, tagged by the bottom bits of the string pointer. It is a
+// high-level wrapper that almost directly corresponds to the interface required
+// by string fields in generated code. It replaces the old std::string* pointer
+// in such cases.
+//
+// The string pointer is tagged to be either a default, externally owned value,
+// a mutable heap allocated value, or an arena allocated value. The object uses
+// a single global instance of an empty string that is used as the initial
+// default value. Fields that have empty default values directly use this global
+// default. Fields that have non empty default values are supported through
+// lazily initialized default values managed by the LazyString class.
+//
+// Generated code and reflection code both ensure that ptr_ is never null.
+// Because ArenaStringPtr is used in oneof unions, its constructor is a NOP and
+// the field is always manually initialized via method calls.
+//
+// See TaggedStringPtr for more information about the types of string values
+// being held, and the mutable and ownership invariants for each type.
+struct PROTOBUF_EXPORT ArenaStringPtr {
+ ArenaStringPtr() = default;
+ constexpr ArenaStringPtr(ExplicitlyConstructedArenaString* default_value,
+ ConstantInitialized)
+ : tagged_ptr_(default_value) {}
+
+ // 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 InitDefault();
+
+ // Similar to `InitDefault` except that it allows the default value to be
+ // initialized to an externally owned string. This method is called from
+ // parsing code. `str` must not be null and outlive this instance.
+ inline void InitExternal(const std::string* str);
+
+ // Called from generated code / reflection runtime only. Resets the value of
+ // this instances to the heap allocated value in `str`. `str` must not be
+ // null. Invokes `arena->Own(str)` to transfer ownership into the arena if
+ // `arena` is not null, else, `str` will be owned by ArenaStringPtr. This
+ // function should only be used to initialize a ArenaStringPtr or on an
+ // instance known to not carry any heap allocated value.
+ inline void InitAllocated(std::string* str, Arena* arena);
+
+ void Set(ConstStringParam value, Arena* arena);
+ void Set(std::string&& value, Arena* arena);
+ void Set(const char* s, Arena* arena);
+ void Set(const char* s, size_t n, Arena* arena);
+
+ void SetBytes(ConstStringParam value, Arena* arena);
+ void SetBytes(std::string&& value, Arena* arena);
+ void SetBytes(const char* s, Arena* arena);
+ void SetBytes(const void* p, size_t n, Arena* arena);
+
+ template <typename RefWrappedType>
+ void Set(std::reference_wrapper<RefWrappedType> const_string_ref,
+ ::google::protobuf::Arena* arena) {
+ Set(const_string_ref.get(), arena);
+ }
+
+ // Returns a mutable std::string reference.
+ // The version accepting a `LazyString` value is used in the generated code to
+ // initialize mutable copies for fields with a non-empty default where the
+ // default value is lazily initialized.
+ std::string* Mutable(Arena* arena);
+ std::string* Mutable(const LazyString& default_value, Arena* arena);
+
+ // Gets a mutable pointer with unspecified contents.
+ // This function is identical to Mutable(), except it is optimized for the
+ // case where the caller is not interested in the current contents. For
+ // example, if the current field is not mutable, it will re-initialize the
+ // value with an empty string rather than a (non-empty) default value.
+ // Likewise, if the current value is a fixed size arena string with contents,
+ // it will be initialized into an empty mutable arena string.
+ std::string* MutableNoCopy(Arena* arena);
+
+ // Basic accessors.
+ PROTOBUF_NDEBUG_INLINE const std::string& Get() const {
+ // Unconditionally mask away the tag.
+ return *tagged_ptr_.Get();
+ }
+
+ // Returns a pointer to the stored contents for this instance.
+ // This method is for internal debugging and tracking purposes only.
+ PROTOBUF_NDEBUG_INLINE const std::string* UnsafeGetPointer() const
+ PROTOBUF_RETURNS_NONNULL {
+ return tagged_ptr_.Get();
+ }
+
+ // Release returns a std::string* 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 the default state.
+ // Used to implement release_<field>() methods on generated classes.
+ PROTOBUF_NODISCARD std::string* Release();
+
+ // Takes a std::string that is heap-allocated, and takes ownership. The
+ // std::string's destructor is registered with the arena. Used to implement
+ // set_allocated_<field> in generated classes.
+ void SetAllocated(std::string* value, Arena* arena);
+
+ // Frees storage (if not on an arena).
+ void Destroy();
+
+ // Clears content, but keeps allocated std::string, to avoid the overhead of
+ // heap operations. After this returns, the content (as seen by the user) will
+ // always be the empty std::string. Assumes that |default_value| is an empty
+ // std::string.
+ void ClearToEmpty();
+
+ // Clears content, assuming that the current value is not the empty
+ // string default.
+ void ClearNonDefaultToEmpty();
+
+ // Clears content, but keeps allocated std::string 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);
+
+ // 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(ArenaStringPtr* rhs,
+ Arena* rhs_arena,
+ ArenaStringPtr* lhs,
+ Arena* lhs_arena);
+
+ // Internal setter used only at parse time to directly set a donated string
+ // value.
+ void UnsafeSetTaggedPointer(TaggedStringPtr value) { tagged_ptr_ = value; }
+ // Generated code only! An optimization, in certain cases the generated
+ // code is certain we can obtain a std::string with no default checks and
+ // tag tests.
+ std::string* UnsafeMutablePointer() PROTOBUF_RETURNS_NONNULL;
+
+ // Returns true if this instances holds an immutable default value.
+ inline bool IsDefault() const { return tagged_ptr_.IsDefault(); }
+
+ private:
+ template <typename... Args>
+ inline std::string* NewString(Arena* arena, Args&&... args) {
+ if (arena == nullptr) {
+ auto* s = new std::string(std::forward<Args>(args)...);
+ return tagged_ptr_.SetAllocated(s);
+ } else {
+ auto* s = Arena::Create<std::string>(arena, std::forward<Args>(args)...);
+ return tagged_ptr_.SetMutableArena(s);
+ }
+ }
+
+ TaggedStringPtr tagged_ptr_;
+
+ bool IsFixedSizeArena() 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;
+ friend class TcParser;
+
+ // Slow paths.
+
+ // MutableSlow requires that !IsString() || IsDefault
+ // Variadic to support 0 args for empty default and 1 arg for LazyString.
+ template <typename... Lazy>
+ std::string* MutableSlow(::google::protobuf::Arena* arena, const Lazy&... lazy_default);
+
+ friend class EpsCopyInputStream;
+};
+
+inline void ArenaStringPtr::InitDefault() {
+ tagged_ptr_ = TaggedStringPtr(&fixed_address_empty_string);
+}
+
+inline void ArenaStringPtr::InitExternal(const std::string* str) {
+ tagged_ptr_.SetDefault(str);
+}
+
+inline void ArenaStringPtr::InitAllocated(std::string* str, Arena* arena) {
+ if (arena != nullptr) {
+ tagged_ptr_.SetMutableArena(str);
+ arena->Own(str);
+ } else {
+ tagged_ptr_.SetAllocated(str);
+ }
+}
+
+inline void ArenaStringPtr::Set(const char* s, Arena* arena) {
+ Set(ConstStringParam{s}, arena);
+}
+
+inline void ArenaStringPtr::Set(const char* s, size_t n, Arena* arena) {
+ Set(ConstStringParam{s, n}, arena);
+}
+
+inline void ArenaStringPtr::SetBytes(ConstStringParam value, Arena* arena) {
+ Set(value, arena);
+}
+
+inline void ArenaStringPtr::SetBytes(std::string&& value, Arena* arena) {
+ Set(std::move(value), arena);
+}
+
+inline void ArenaStringPtr::SetBytes(const char* s, Arena* arena) {
+ Set(s, arena);
+}
+
+inline void ArenaStringPtr::SetBytes(const void* p, size_t n, Arena* arena) {
+ Set(ConstStringParam{static_cast<const char*>(p), n}, arena);
+}
+
+// Make sure rhs_arena allocated rhs, and lhs_arena allocated lhs.
+inline PROTOBUF_NDEBUG_INLINE void ArenaStringPtr::InternalSwap( //
+ ArenaStringPtr* rhs, Arena* rhs_arena, //
+ ArenaStringPtr* lhs, Arena* lhs_arena) {
+ // Silence unused variable warnings in release buildls.
+ (void)rhs_arena;
+ (void)lhs_arena;
+ std::swap(lhs->tagged_ptr_, rhs->tagged_ptr_);
+#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ auto force_realloc = [](ArenaStringPtr* p, Arena* arena) {
+ if (p->IsDefault()) return;
+ std::string* old_value = p->tagged_ptr_.Get();
+ std::string* new_value =
+ p->IsFixedSizeArena()
+ ? Arena::Create<std::string>(arena, *old_value)
+ : Arena::Create<std::string>(arena, std::move(*old_value));
+ if (arena == nullptr) {
+ delete old_value;
+ p->tagged_ptr_.SetAllocated(new_value);
+ } else {
+ p->tagged_ptr_.SetMutableArena(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 std::string* ArenaStringPtr::UnsafeMutablePointer() {
+ GOOGLE_DCHECK(tagged_ptr_.IsMutable());
+ GOOGLE_DCHECK(tagged_ptr_.Get() != nullptr);
+ return tagged_ptr_.Get();
+}
+
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_ARENASTRING_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/arenaz_sampler.cc b/toolkit/components/protobuf/src/google/protobuf/arenaz_sampler.cc
new file mode 100644
index 0000000000..0eac693d98
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/arenaz_sampler.cc
@@ -0,0 +1,177 @@
+// 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/arenaz_sampler.h>
+
+#include <atomic>
+#include <cstdint>
+#include <limits>
+
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+ThreadSafeArenazSampler& GlobalThreadSafeArenazSampler() {
+ static auto* sampler = new ThreadSafeArenazSampler();
+ return *sampler;
+}
+
+void UnsampleSlow(ThreadSafeArenaStats* info) {
+ GlobalThreadSafeArenazSampler().Unregister(info);
+}
+
+#if defined(PROTOBUF_ARENAZ_SAMPLE)
+namespace {
+
+PROTOBUF_CONSTINIT std::atomic<bool> g_arenaz_enabled{true};
+PROTOBUF_CONSTINIT std::atomic<int32_t> g_arenaz_sample_parameter{1 << 10};
+PROTOBUF_THREAD_LOCAL absl::profiling_internal::ExponentialBiased
+ g_exponential_biased_generator;
+
+} // namespace
+
+PROTOBUF_THREAD_LOCAL int64_t global_next_sample = 1LL << 10;
+
+ThreadSafeArenaStats::ThreadSafeArenaStats() { PrepareForSampling(); }
+ThreadSafeArenaStats::~ThreadSafeArenaStats() = default;
+
+void ThreadSafeArenaStats::PrepareForSampling() {
+ num_allocations.store(0, std::memory_order_relaxed);
+ num_resets.store(0, std::memory_order_relaxed);
+ bytes_requested.store(0, std::memory_order_relaxed);
+ bytes_allocated.store(0, std::memory_order_relaxed);
+ bytes_wasted.store(0, std::memory_order_relaxed);
+ max_bytes_allocated.store(0, std::memory_order_relaxed);
+ thread_ids.store(0, std::memory_order_relaxed);
+ // The inliner makes hardcoded skip_count difficult (especially when combined
+ // with LTO). We use the ability to exclude stacks by regex when encoding
+ // instead.
+ depth = absl::GetStackTrace(stack, kMaxStackDepth, /* skip_count= */ 0);
+}
+
+void RecordResetSlow(ThreadSafeArenaStats* info) {
+ const size_t max_bytes =
+ info->max_bytes_allocated.load(std::memory_order_relaxed);
+ const size_t allocated_bytes =
+ info->bytes_allocated.load(std::memory_order_relaxed);
+ if (max_bytes < allocated_bytes) {
+ info->max_bytes_allocated.store(allocated_bytes);
+ }
+ info->bytes_requested.store(0, std::memory_order_relaxed);
+ info->bytes_allocated.store(0, std::memory_order_relaxed);
+ info->bytes_wasted.fetch_add(0, std::memory_order_relaxed);
+ info->num_allocations.fetch_add(0, std::memory_order_relaxed);
+ info->num_resets.fetch_add(1, std::memory_order_relaxed);
+}
+
+void RecordAllocateSlow(ThreadSafeArenaStats* info, size_t requested,
+ size_t allocated, size_t wasted) {
+ info->bytes_requested.fetch_add(requested, std::memory_order_relaxed);
+ info->bytes_allocated.fetch_add(allocated, std::memory_order_relaxed);
+ info->bytes_wasted.fetch_add(wasted, std::memory_order_relaxed);
+ info->num_allocations.fetch_add(1, std::memory_order_relaxed);
+ const uint64_t tid = (1ULL << (GetCachedTID() % 63));
+ const uint64_t thread_ids = info->thread_ids.load(std::memory_order_relaxed);
+ if (!(thread_ids & tid)) {
+ info->thread_ids.store(thread_ids | tid, std::memory_order_relaxed);
+ }
+}
+
+ThreadSafeArenaStats* SampleSlow(int64_t* next_sample) {
+ bool first = *next_sample < 0;
+ *next_sample = g_exponential_biased_generator.GetStride(
+ g_arenaz_sample_parameter.load(std::memory_order_relaxed));
+ // Small values of interval are equivalent to just sampling next time.
+ ABSL_ASSERT(*next_sample >= 1);
+
+ // g_arenaz_enabled can be dynamically flipped, we need to set a threshold low
+ // enough that we will start sampling in a reasonable time, so we just use the
+ // default sampling rate.
+ if (!g_arenaz_enabled.load(std::memory_order_relaxed)) return nullptr;
+ // We will only be negative on our first count, so we should just retry in
+ // that case.
+ if (first) {
+ if (PROTOBUF_PREDICT_TRUE(--*next_sample > 0)) return nullptr;
+ return SampleSlow(next_sample);
+ }
+
+ return GlobalThreadSafeArenazSampler().Register();
+}
+
+void SetThreadSafeArenazEnabled(bool enabled) {
+ g_arenaz_enabled.store(enabled, std::memory_order_release);
+}
+
+void SetThreadSafeArenazSampleParameter(int32_t rate) {
+ if (rate > 0) {
+ g_arenaz_sample_parameter.store(rate, std::memory_order_release);
+ } else {
+ ABSL_RAW_LOG(ERROR, "Invalid thread safe arenaz sample rate: %lld",
+ static_cast<long long>(rate)); // NOLINT(runtime/int)
+ }
+}
+
+void SetThreadSafeArenazMaxSamples(int32_t max) {
+ if (max > 0) {
+ GlobalThreadSafeArenazSampler().SetMaxSamples(max);
+ } else {
+ ABSL_RAW_LOG(ERROR, "Invalid thread safe arenaz max samples: %lld",
+ static_cast<long long>(max)); // NOLINT(runtime/int)
+ }
+}
+
+void SetThreadSafeArenazGlobalNextSample(int64_t next_sample) {
+ if (next_sample >= 0) {
+ global_next_sample = next_sample;
+ } else {
+ ABSL_RAW_LOG(ERROR, "Invalid thread safe arenaz next sample: %lld",
+ static_cast<long long>(next_sample)); // NOLINT(runtime/int)
+ }
+}
+
+#else
+ThreadSafeArenaStats* SampleSlow(int64_t* next_sample) {
+ *next_sample = std::numeric_limits<int64_t>::max();
+ return nullptr;
+}
+
+void SetThreadSafeArenazEnabled(bool enabled) {}
+void SetThreadSafeArenazSampleParameter(int32_t rate) {}
+void SetThreadSafeArenazMaxSamples(int32_t max) {}
+void SetThreadSafeArenazGlobalNextSample(int64_t next_sample) {}
+#endif // defined(PROTOBUF_ARENAZ_SAMPLE)
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/toolkit/components/protobuf/src/google/protobuf/arenaz_sampler.h b/toolkit/components/protobuf/src/google/protobuf/arenaz_sampler.h
new file mode 100644
index 0000000000..b04b0cc678
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/arenaz_sampler.h
@@ -0,0 +1,207 @@
+// 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_SRC_GOOGLE_PROTOBUF_ARENAZ_SAMPLER_H__
+#define GOOGLE_PROTOBUF_SRC_GOOGLE_PROTOBUF_ARENAZ_SAMPLER_H__
+
+#include <atomic>
+#include <cstddef>
+#include <cstdint>
+
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+#if defined(PROTOBUF_ARENAZ_SAMPLE)
+struct ThreadSafeArenaStats;
+void RecordResetSlow(ThreadSafeArenaStats* info);
+void RecordAllocateSlow(ThreadSafeArenaStats* info, size_t requested,
+ size_t allocated, size_t wasted);
+// Stores information about a sampled thread safe arena. All mutations to this
+// *must* be made through `Record*` functions below. All reads from this *must*
+// only occur in the callback to `ThreadSafeArenazSampler::Iterate`.
+struct ThreadSafeArenaStats
+ : public absl::profiling_internal::Sample<ThreadSafeArenaStats> {
+ // Constructs the object but does not fill in any fields.
+ ThreadSafeArenaStats();
+ ~ThreadSafeArenaStats();
+
+ // Puts the object into a clean state, fills in the logically `const` members,
+ // blocking for any readers that are currently sampling the object.
+ void PrepareForSampling() ABSL_EXCLUSIVE_LOCKS_REQUIRED(init_mu);
+
+ // These fields are mutated by the various Record* APIs and need to be
+ // thread-safe.
+ std::atomic<int> num_allocations;
+ std::atomic<int> num_resets;
+ std::atomic<size_t> bytes_requested;
+ std::atomic<size_t> bytes_allocated;
+ std::atomic<size_t> bytes_wasted;
+ // Records the largest size an arena ever had. Maintained across resets.
+ std::atomic<size_t> max_bytes_allocated;
+ // Bit i when set to 1 indicates that a thread with tid % 63 = i accessed the
+ // underlying arena. The field is maintained across resets.
+ std::atomic<uint64_t> thread_ids;
+
+ // All of the fields below are set by `PrepareForSampling`, they must not
+ // be mutated in `Record*` functions. They are logically `const` in that
+ // sense. These are guarded by init_mu, but that is not externalized to
+ // clients, who can only read them during
+ // `ThreadSafeArenazSampler::Iterate` which will hold the lock.
+ static constexpr int kMaxStackDepth = 64;
+ int32_t depth;
+ void* stack[kMaxStackDepth];
+ static void RecordAllocateStats(ThreadSafeArenaStats* info, size_t requested,
+ size_t allocated, size_t wasted) {
+ if (PROTOBUF_PREDICT_TRUE(info == nullptr)) return;
+ RecordAllocateSlow(info, requested, allocated, wasted);
+ }
+};
+
+ThreadSafeArenaStats* SampleSlow(int64_t* next_sample);
+void UnsampleSlow(ThreadSafeArenaStats* info);
+
+class ThreadSafeArenaStatsHandle {
+ public:
+ explicit ThreadSafeArenaStatsHandle() = default;
+ explicit ThreadSafeArenaStatsHandle(ThreadSafeArenaStats* info)
+ : info_(info) {}
+
+ ~ThreadSafeArenaStatsHandle() {
+ if (PROTOBUF_PREDICT_TRUE(info_ == nullptr)) return;
+ UnsampleSlow(info_);
+ }
+
+ ThreadSafeArenaStatsHandle(ThreadSafeArenaStatsHandle&& other) noexcept
+ : info_(absl::exchange(other.info_, nullptr)) {}
+
+ ThreadSafeArenaStatsHandle& operator=(
+ ThreadSafeArenaStatsHandle&& other) noexcept {
+ if (PROTOBUF_PREDICT_FALSE(info_ != nullptr)) {
+ UnsampleSlow(info_);
+ }
+ info_ = absl::exchange(other.info_, nullptr);
+ return *this;
+ }
+
+ void RecordReset() {
+ if (PROTOBUF_PREDICT_TRUE(info_ == nullptr)) return;
+ RecordResetSlow(info_);
+ }
+
+ ThreadSafeArenaStats* MutableStats() { return info_; }
+
+ friend void swap(ThreadSafeArenaStatsHandle& lhs,
+ ThreadSafeArenaStatsHandle& rhs) {
+ std::swap(lhs.info_, rhs.info_);
+ }
+
+ friend class ThreadSafeArenaStatsHandlePeer;
+
+ private:
+ ThreadSafeArenaStats* info_ = nullptr;
+};
+
+using ThreadSafeArenazSampler =
+ ::absl::profiling_internal::SampleRecorder<ThreadSafeArenaStats>;
+
+extern PROTOBUF_THREAD_LOCAL int64_t global_next_sample;
+
+// Returns an RAII sampling handle that manages registration and unregistation
+// with the global sampler.
+inline ThreadSafeArenaStatsHandle Sample() {
+ if (PROTOBUF_PREDICT_TRUE(--global_next_sample > 0)) {
+ return ThreadSafeArenaStatsHandle(nullptr);
+ }
+ return ThreadSafeArenaStatsHandle(SampleSlow(&global_next_sample));
+}
+
+#else
+struct ThreadSafeArenaStats {
+ static void RecordAllocateStats(ThreadSafeArenaStats*, size_t /*requested*/,
+ size_t /*allocated*/, size_t /*wasted*/) {}
+};
+
+ThreadSafeArenaStats* SampleSlow(int64_t* next_sample);
+void UnsampleSlow(ThreadSafeArenaStats* info);
+
+class ThreadSafeArenaStatsHandle {
+ public:
+ explicit ThreadSafeArenaStatsHandle() = default;
+ explicit ThreadSafeArenaStatsHandle(ThreadSafeArenaStats*) {}
+
+ void RecordReset() {}
+
+ ThreadSafeArenaStats* MutableStats() { return nullptr; }
+
+ friend void swap(ThreadSafeArenaStatsHandle&, ThreadSafeArenaStatsHandle&) {}
+
+ private:
+ friend class ThreadSafeArenaStatsHandlePeer;
+};
+
+class ThreadSafeArenazSampler {
+ public:
+ void Unregister(ThreadSafeArenaStats*) {}
+ void SetMaxSamples(int32_t) {}
+};
+
+// Returns an RAII sampling handle that manages registration and unregistation
+// with the global sampler.
+inline ThreadSafeArenaStatsHandle Sample() {
+ return ThreadSafeArenaStatsHandle(nullptr);
+}
+#endif // defined(PROTOBUF_ARENAZ_SAMPLE)
+
+// Returns a global Sampler.
+ThreadSafeArenazSampler& GlobalThreadSafeArenazSampler();
+
+// Enables or disables sampling for thread safe arenas.
+void SetThreadSafeArenazEnabled(bool enabled);
+
+// Sets the rate at which thread safe arena will be sampled.
+void SetThreadSafeArenazSampleParameter(int32_t rate);
+
+// Sets a soft max for the number of samples that will be kept.
+void SetThreadSafeArenazMaxSamples(int32_t max);
+
+// Sets the current value for when arenas should be next sampled.
+void SetThreadSafeArenazGlobalNextSample(int64_t next_sample);
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+#endif // GOOGLE_PROTOBUF_SRC_PROTOBUF_ARENAZ_SAMPLER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/descriptor.cc b/toolkit/components/protobuf/src/google/protobuf/descriptor.cc
new file mode 100644
index 0000000000..5f3427dc72
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/descriptor.cc
@@ -0,0 +1,8340 @@
+// 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 <sstream>
+#include <string>
+#include <type_traits>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/once.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_impl.h>
+#include <google/protobuf/stubs/casts.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/io/strtod.h>
+#include <google/protobuf/port.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/unknown_field_set.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. :(
+
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+namespace {
+const int kPackageLimit = 100;
+
+// 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;
+}
+
+std::string ToCamelCase(const std::string& input, bool lower_first) {
+ bool capitalize_next = !lower_first;
+ std::string 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;
+}
+
+std::string ToJsonName(const std::string& input) {
+ bool capitalize_next = false;
+ std::string 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;
+}
+
+// Backport of fold expressions for the comma operator to C++11.
+// Usage: Fold({expr...});
+// Guaranteed to evaluate left-to-right
+struct ExpressionEater {
+ template <typename T>
+ ExpressionEater(T&&) {} // NOLINT
+};
+void Fold(std::initializer_list<ExpressionEater>) {}
+
+template <int R>
+constexpr size_t RoundUpTo(size_t n) {
+ static_assert((R & (R - 1)) == 0, "Must be power of two");
+ return (n + (R - 1)) & ~(R - 1);
+}
+
+constexpr size_t Max(size_t a, size_t b) { return a > b ? a : b; }
+template <typename T, typename... Ts>
+constexpr size_t Max(T a, Ts... b) {
+ return Max(a, Max(b...));
+}
+
+template <typename T>
+constexpr size_t EffectiveAlignof() {
+ // `char` is special in that it gets aligned to 8. It is where we drop the
+ // trivial structs.
+ return std::is_same<T, char>::value ? 8 : alignof(T);
+}
+
+template <int align, typename U, typename... T>
+using AppendIfAlign =
+ typename std::conditional<EffectiveAlignof<U>() == align, void (*)(T..., U),
+ void (*)(T...)>::type;
+
+// Metafunction to sort types in descending order of alignment.
+// Useful for the flat allocator to ensure proper alignment of all elements
+// without having to add padding.
+// Instead of implementing a proper sort metafunction we just do a
+// filter+merge, which is much simpler to write as a metafunction.
+// We have a fixed set of alignments we can filter on.
+// For simplicity we use a function pointer as a type list.
+template <typename In, typename T16, typename T8, typename T4, typename T2,
+ typename T1>
+struct TypeListSortImpl;
+
+template <typename... T16, typename... T8, typename... T4, typename... T2,
+ typename... T1>
+struct TypeListSortImpl<void (*)(), void (*)(T16...), void (*)(T8...),
+ void (*)(T4...), void (*)(T2...), void (*)(T1...)> {
+ using type = void (*)(T16..., T8..., T4..., T2..., T1...);
+};
+
+template <typename First, typename... Rest, typename... T16, typename... T8,
+ typename... T4, typename... T2, typename... T1>
+struct TypeListSortImpl<void (*)(First, Rest...), void (*)(T16...),
+ void (*)(T8...), void (*)(T4...), void (*)(T2...),
+ void (*)(T1...)> {
+ using type = typename TypeListSortImpl<
+ void (*)(Rest...), AppendIfAlign<16, First, T16...>,
+ AppendIfAlign<8, First, T8...>, AppendIfAlign<4, First, T4...>,
+ AppendIfAlign<2, First, T2...>, AppendIfAlign<1, First, T1...>>::type;
+};
+
+template <typename... T>
+using SortByAlignment =
+ typename TypeListSortImpl<void (*)(T...), void (*)(), void (*)(),
+ void (*)(), void (*)(), void (*)()>::type;
+
+template <template <typename...> class C, typename... T>
+auto ApplyTypeList(void (*)(T...)) -> C<T...>;
+
+template <typename T>
+constexpr int FindTypeIndex() {
+ return -1;
+}
+
+template <typename T, typename T1, typename... Ts>
+constexpr int FindTypeIndex() {
+ return std::is_same<T, T1>::value ? 0 : FindTypeIndex<T, Ts...>() + 1;
+}
+
+// A type to value map, where the possible keys as specified in `Keys...`.
+// The values for key `K` is `ValueT<K>`
+template <template <typename> class ValueT, typename... Keys>
+class TypeMap {
+ public:
+ template <typename K>
+ ValueT<K>& Get() {
+ return static_cast<Base<K>&>(payload_).value;
+ }
+
+ template <typename K>
+ const ValueT<K>& Get() const {
+ return static_cast<const Base<K>&>(payload_).value;
+ }
+
+ private:
+ template <typename K>
+ struct Base {
+ ValueT<K> value{};
+ };
+ struct Payload : Base<Keys>... {};
+ Payload payload_;
+};
+
+template <typename T>
+using IntT = int;
+template <typename T>
+using PointerT = T*;
+
+// Manages an allocation of sequential arrays of type `T...`.
+// It is more space efficient than storing N (ptr, size) pairs, by storing only
+// the pointer to the head and the boundaries between the arrays.
+template <typename... T>
+class FlatAllocation {
+ public:
+ static constexpr size_t kMaxAlign = Max(alignof(T)...);
+
+ FlatAllocation(const TypeMap<IntT, T...>& ends) : ends_(ends) {
+ // The arrays start just after FlatAllocation, so adjust the ends.
+ Fold({(ends_.template Get<T>() +=
+ RoundUpTo<kMaxAlign>(sizeof(FlatAllocation)))...});
+ Fold({Init<T>()...});
+ }
+
+ void Destroy() {
+ Fold({Destroy<T>()...});
+ internal::SizedDelete(this, total_bytes());
+ }
+
+ template <int I>
+ using type = typename std::tuple_element<I, std::tuple<T...>>::type;
+
+ // Gets a tuple of the head pointers for the arrays
+ TypeMap<PointerT, T...> Pointers() const {
+ TypeMap<PointerT, T...> out;
+ Fold({(out.template Get<T>() = Begin<T>())...});
+ return out;
+ }
+
+
+ private:
+ // Total number of bytes used by all arrays.
+ int total_bytes() const {
+ // Get the last end.
+ return ends_.template Get<typename std::tuple_element<
+ sizeof...(T) - 1, std::tuple<T...>>::type>();
+ }
+
+
+ template <typename U>
+ int BeginOffset() const {
+ constexpr int type_index = FindTypeIndex<U, T...>();
+ // Avoid a negative value here to keep it compiling when type_index == 0
+ constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
+ using PrevType =
+ typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
+ // Ensure the types are properly aligned.
+ static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
+ return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
+ : ends_.template Get<PrevType>();
+ }
+
+ template <typename U>
+ int EndOffset() const {
+ return ends_.template Get<U>();
+ }
+
+ // Avoid the reinterpret_cast if the array is empty.
+ // Clang's Control Flow Integrity does not like the cast pointing to memory
+ // that is not yet initialized to be of that type.
+ // (from -fsanitize=cfi-unrelated-cast)
+ template <typename U>
+ U* Begin() const {
+ int begin = BeginOffset<U>(), end = EndOffset<U>();
+ if (begin == end) return nullptr;
+ return reinterpret_cast<U*>(data() + begin);
+ }
+
+ template <typename U>
+ U* End() const {
+ int begin = BeginOffset<U>(), end = EndOffset<U>();
+ if (begin == end) return nullptr;
+ return reinterpret_cast<U*>(data() + end);
+ }
+
+ template <typename U>
+ bool Init() {
+ // Skip for the `char` block. No need to zero initialize it.
+ if (std::is_same<U, char>::value) return true;
+ for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
+ p != end; p += sizeof(U)) {
+ ::new (p) U{};
+ }
+ return true;
+ }
+
+ template <typename U>
+ bool Destroy() {
+ if (std::is_trivially_destructible<U>::value) return true;
+ for (U* it = Begin<U>(), *end = End<U>(); it != end; ++it) {
+ it->~U();
+ }
+ return true;
+ }
+
+ char* data() const {
+ return const_cast<char*>(reinterpret_cast<const char*>(this));
+ }
+
+ TypeMap<IntT, T...> ends_;
+};
+
+template <typename... T>
+TypeMap<IntT, T...> CalculateEnds(const TypeMap<IntT, T...>& sizes) {
+ int total = 0;
+ TypeMap<IntT, T...> out;
+ Fold({(out.template Get<T>() = total +=
+ sizeof(T) * sizes.template Get<T>())...});
+ return out;
+}
+
+// The implementation for FlatAllocator below.
+// This separate class template makes it easier to have methods that fold on
+// `T...`.
+template <typename... T>
+class FlatAllocatorImpl {
+ public:
+ using Allocation = FlatAllocation<T...>;
+
+ template <typename U>
+ void PlanArray(int array_size) {
+ // We can't call PlanArray after FinalizePlanning has been called.
+ GOOGLE_CHECK(!has_allocated());
+ if (std::is_trivially_destructible<U>::value) {
+ // Trivial types are aligned to 8 bytes.
+ static_assert(alignof(U) <= 8, "");
+ total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
+ } else {
+ // Since we can't use `if constexpr`, just make the expression compile
+ // when this path is not taken.
+ using TypeToUse =
+ typename std::conditional<std::is_trivially_destructible<U>::value,
+ char, U>::type;
+ total_.template Get<TypeToUse>() += array_size;
+ }
+ }
+
+ template <typename U>
+ U* AllocateArray(int array_size) {
+ constexpr bool trivial = std::is_trivially_destructible<U>::value;
+ using TypeToUse = typename std::conditional<trivial, char, U>::type;
+
+ // We can only allocate after FinalizePlanning has been called.
+ GOOGLE_CHECK(has_allocated());
+
+ TypeToUse*& data = pointers_.template Get<TypeToUse>();
+ int& used = used_.template Get<TypeToUse>();
+ U* res = reinterpret_cast<U*>(data + used);
+ used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
+ GOOGLE_CHECK_LE(used, total_.template Get<TypeToUse>());
+ return res;
+ }
+
+ template <typename... In>
+ const std::string* AllocateStrings(In&&... in) {
+ std::string* strings = AllocateArray<std::string>(sizeof...(in));
+ std::string* res = strings;
+ Fold({(*strings++ = std::string(std::forward<In>(in)))...});
+ return res;
+ }
+
+ // Allocate all 5 names of the field:
+ // name, full name, lowercase, camelcase and json.
+ // It 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.
+ void PlanFieldNames(const std::string& name,
+ const std::string* opt_json_name) {
+ GOOGLE_CHECK(!has_allocated());
+
+ // Fast path for snake_case names, which follow the style guide.
+ if (opt_json_name == nullptr) {
+ switch (GetFieldNameCase(name)) {
+ case FieldNameCase::kAllLower:
+ // Case 1: they are all the same.
+ return PlanArray<std::string>(2);
+ case FieldNameCase::kSnakeCase:
+ // Case 2: name==lower, camel==json
+ return PlanArray<std::string>(3);
+ default:
+ break;
+ }
+ }
+
+ std::string lowercase_name = name;
+ LowerString(&lowercase_name);
+
+ std::string camelcase_name = ToCamelCase(name, /* lower_first = */ true);
+ std::string json_name =
+ opt_json_name != nullptr ? *opt_json_name : ToJsonName(name);
+
+ StringPiece all_names[] = {name, lowercase_name, camelcase_name,
+ json_name};
+ std::sort(all_names, all_names + 4);
+ int unique =
+ static_cast<int>(std::unique(all_names, all_names + 4) - all_names);
+
+ PlanArray<std::string>(unique + 1);
+ }
+
+ struct FieldNamesResult {
+ const std::string* array;
+ int lowercase_index;
+ int camelcase_index;
+ int json_index;
+ };
+ FieldNamesResult AllocateFieldNames(const std::string& name,
+ const std::string& scope,
+ const std::string* opt_json_name) {
+ GOOGLE_CHECK(has_allocated());
+
+ std::string full_name =
+ scope.empty() ? name : StrCat(scope, ".", name);
+
+ // Fast path for snake_case names, which follow the style guide.
+ if (opt_json_name == nullptr) {
+ switch (GetFieldNameCase(name)) {
+ case FieldNameCase::kAllLower:
+ // Case 1: they are all the same.
+ return {AllocateStrings(name, std::move(full_name)), 0, 0, 0};
+ case FieldNameCase::kSnakeCase:
+ // Case 2: name==lower, camel==json
+ return {AllocateStrings(name, std::move(full_name),
+ ToCamelCase(name, /* lower_first = */ true)),
+ 0, 2, 2};
+ default:
+ break;
+ }
+ }
+
+ std::vector<std::string> names;
+ names.push_back(name);
+ names.push_back(std::move(full_name));
+
+ const auto push_name = [&](std::string new_name) {
+ for (size_t i = 0; i < names.size(); ++i) {
+ // Do not compare the full_name. It is unlikely to match, except in
+ // custom json_name. We are not taking this into account in
+ // PlanFieldNames so better to not try it.
+ if (i == 1) continue;
+ if (names[i] == new_name) return i;
+ }
+ names.push_back(std::move(new_name));
+ return names.size() - 1;
+ };
+
+ FieldNamesResult result{nullptr, 0, 0, 0};
+
+ std::string lowercase_name = name;
+ LowerString(&lowercase_name);
+ result.lowercase_index = push_name(std::move(lowercase_name));
+ result.camelcase_index =
+ push_name(ToCamelCase(name, /* lower_first = */ true));
+ result.json_index =
+ push_name(opt_json_name != nullptr ? *opt_json_name : ToJsonName(name));
+
+ std::string* all_names = AllocateArray<std::string>(names.size());
+ result.array = all_names;
+ std::move(names.begin(), names.end(), all_names);
+
+ return result;
+ }
+
+ template <typename Alloc>
+ void FinalizePlanning(Alloc& alloc) {
+ GOOGLE_CHECK(!has_allocated());
+
+ pointers_ = alloc->CreateFlatAlloc(total_)->Pointers();
+
+ GOOGLE_CHECK(has_allocated());
+ }
+
+ void ExpectConsumed() const {
+ // We verify that we consumed all the memory requested if there was no
+ // error in processing.
+ Fold({ExpectConsumed<T>()...});
+ }
+
+ private:
+ bool has_allocated() const {
+ return pointers_.template Get<char>() != nullptr;
+ }
+
+ static bool IsLower(char c) { return 'a' <= c && c <= 'z'; }
+ static bool IsDigit(char c) { return '0' <= c && c <= '9'; }
+ static bool IsLowerOrDigit(char c) { return IsLower(c) || IsDigit(c); }
+
+ enum class FieldNameCase { kAllLower, kSnakeCase, kOther };
+ FieldNameCase GetFieldNameCase(const std::string& name) {
+ if (!IsLower(name[0])) return FieldNameCase::kOther;
+ FieldNameCase best = FieldNameCase::kAllLower;
+ for (char c : name) {
+ if (IsLowerOrDigit(c)) {
+ // nothing to do
+ } else if (c == '_') {
+ best = FieldNameCase::kSnakeCase;
+ } else {
+ return FieldNameCase::kOther;
+ }
+ }
+ return best;
+ }
+
+ template <typename U>
+ bool ExpectConsumed() const {
+ GOOGLE_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
+ return true;
+ }
+
+ TypeMap<PointerT, T...> pointers_;
+ TypeMap<IntT, T...> total_;
+ TypeMap<IntT, T...> used_;
+};
+
+} // namespace
+
+class Symbol {
+ public:
+ enum Type {
+ NULL_SYMBOL,
+ MESSAGE,
+ FIELD,
+ ONEOF,
+ ENUM,
+ ENUM_VALUE,
+ ENUM_VALUE_OTHER_PARENT,
+ SERVICE,
+ METHOD,
+ FULL_PACKAGE,
+ SUB_PACKAGE,
+ QUERY_KEY
+ };
+
+ Symbol() {
+ static constexpr internal::SymbolBase null_symbol{};
+ static_assert(null_symbol.symbol_type_ == NULL_SYMBOL, "");
+ // Initialize with a sentinel to make sure `ptr_` is never null.
+ ptr_ = &null_symbol;
+ }
+
+ // 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)
+ DEFINE_MEMBERS(FileDescriptor, FULL_PACKAGE, file_descriptor)
+
+ // We use a special node for subpackage FileDescriptor.
+ // It is potentially added to the table with multiple different names, so we
+ // need a separate place to put the name.
+ struct Subpackage : internal::SymbolBase {
+ int name_size;
+ const FileDescriptor* file;
+ };
+ DEFINE_MEMBERS(Subpackage, SUB_PACKAGE, sub_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.
+ // TODO(b/215557658): If we templetize QueryKey on the expected object type we
+ // can skip the switches for the eq function altogether.
+ struct QueryKey : internal::SymbolBase {
+ StringPiece name;
+ const void* parent;
+ int field_number;
+
+ // Adaptor functions to look like a Symbol to the comparators.
+ StringPiece full_name() const { return name; }
+ std::pair<const void*, int> parent_number_key() const {
+ return {parent, field_number};
+ }
+ std::pair<const void*, StringPiece> parent_name_key() const {
+ return {parent, name};
+ }
+ };
+ // This constructor is implicit to allow for non-transparent lookups when
+ // necessary.
+ // For transparent lookup cases we query directly with the object without the
+ // type erasure layer.
+ Symbol(QueryKey& value) : ptr_(&value) { // NOLINT
+ value.symbol_type_ = QUERY_KEY;
+ }
+ const QueryKey* query_key() const {
+ return type() == QUERY_KEY ? static_cast<const QueryKey*>(ptr_) : nullptr;
+ }
+#undef DEFINE_MEMBERS
+
+ Type type() const { return 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 IsType() || IsPackage() || type() == SERVICE;
+ }
+ bool IsPackage() const {
+ return type() == FULL_PACKAGE || type() == SUB_PACKAGE;
+ }
+
+ 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 FULL_PACKAGE:
+ return file_descriptor();
+ case SUB_PACKAGE:
+ return sub_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 FULL_PACKAGE:
+ return file_descriptor()->package();
+ case SUB_PACKAGE:
+ return StringPiece(sub_package_file_descriptor()->file->package())
+ .substr(0, sub_package_file_descriptor()->name_size);
+ case QUERY_KEY:
+ return query_key()->full_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_name_key();
+ 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_number_key();
+ 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 {
+
+std::string EnumValueToPascalCase(const std::string& input) {
+ bool next_upper = true;
+ std::string 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.
+ std::string 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 std::string(str);
+ }
+ }
+
+ // If we didn't make it through the prefix, we've failed to strip the
+ // prefix.
+ if (j < prefix_.size()) {
+ return std::string(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 std::string(str);
+ }
+
+ // We successfully stripped the prefix.
+ str.remove_prefix(i);
+ return std::string(str);
+ }
+
+ private:
+ std::string 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 {
+ using is_transparent = void;
+
+ template <typename T>
+ size_t operator()(const T& s) const {
+ return HASH_FXN<StringPiece>{}(s.full_name());
+ }
+};
+struct SymbolByFullNameEq {
+ using is_transparent = void;
+
+ template <typename T, typename U>
+ bool operator()(const T& a, const U& b) const {
+ return a.full_name() == b.full_name();
+ }
+};
+using SymbolsByNameSet =
+ HASH_SET<Symbol, SymbolByFullNameHash, SymbolByFullNameEq>;
+
+struct SymbolByParentHash {
+ using is_transparent = void;
+
+ template <typename T>
+ size_t operator()(const T& s) const {
+ return PointerStringPairHash{}(s.parent_name_key());
+ }
+};
+struct SymbolByParentEq {
+ using is_transparent = void;
+
+ template <typename T, typename U>
+ bool operator()(const T& a, const U& 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 {
+ using is_transparent = void;
+
+ template <typename T>
+ size_t operator()(const T& s) const {
+ return PointerIntegerPairHash<std::pair<const void*, int>>{}(
+ s.parent_number_key());
+ }
+};
+struct FieldsByNumberEq {
+ using is_transparent = void;
+
+ template <typename T, typename U>
+ bool operator()(const T& a, const U& 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<std::string, const SourceCodeInfo_Location*>
+ LocationsByPathMap;
+
+std::set<std::string>* NewAllowedProto3Extendee() {
+ auto allowed_proto3_extendees = new std::set<std::string>;
+ const char* kOptionNames[] = {
+ "FileOptions", "MessageOptions", "FieldOptions",
+ "EnumOptions", "EnumValueOptions", "ServiceOptions",
+ "MethodOptions", "OneofOptions", "ExtensionRangeOptions"};
+ 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(std::string("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(std::string("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 std::string& name) {
+ static auto allowed_proto3_extendees =
+ internal::OnShutdownDelete(NewAllowedProto3Extendee());
+ return allowed_proto3_extendees->find(name) !=
+ allowed_proto3_extendees->end();
+}
+} // anonymous namespace
+
+// 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.
+ bool AddAliasUnderParent(const void* parent, const std::string& name,
+ Symbol symbol);
+ bool AddFieldByNumber(FieldDescriptor* field);
+ bool AddEnumValueByNumber(EnumValueDescriptor* value);
+
+ // 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 internal::once_flag fields_by_lowercase_name_once_;
+ mutable internal::once_flag fields_by_camelcase_name_once_;
+ // Make these fields atomic to avoid race conditions with
+ // GetEstimatedOwnedMemoryBytesSize. Once the pointer is set the map won't
+ // change anymore.
+ mutable std::atomic<const FieldsByNameMap*> fields_by_lowercase_name_{};
+ mutable std::atomic<const FieldsByNameMap*> fields_by_camelcase_name_{};
+ 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_;
+};
+
+namespace internal {
+
+// Small sequential allocator to be used within a single file.
+// Most of the memory for a single FileDescriptor and everything under it is
+// allocated in a single block of memory, with the FlatAllocator giving it out
+// in parts later.
+// The code first plans the total number of bytes needed by calling PlanArray
+// with all the allocations that will happen afterwards, then calls
+// FinalizePlanning passing the underlying allocator (the DescriptorPool::Tables
+// instance), and then proceeds to get the memory via
+// `AllocateArray`/`AllocateString` calls. The calls to PlanArray and
+// The calls have to match between planning and allocating, though not
+// necessarily in the same order.
+class FlatAllocator
+ : public decltype(ApplyTypeList<FlatAllocatorImpl>(
+ SortByAlignment<char, std::string, SourceCodeInfo,
+ FileDescriptorTables,
+ // Option types
+ MessageOptions, FieldOptions, EnumOptions,
+ EnumValueOptions, ExtensionRangeOptions, OneofOptions,
+ ServiceOptions, MethodOptions, FileOptions>())) {};
+
+} // namespace internal
+
+// ===================================================================
+// 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<std::string> 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<std::string> 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<std::string> 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<std::string, 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 std::string& 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 some bytes which will be reclaimed when the pool is
+ // destroyed. Memory is aligned to 8 bytes.
+ void* AllocateBytes(int size);
+
+ // Create a FlatAllocation for the corresponding sizes.
+ // All objects within it will be default constructed.
+ // The whole allocation, including the non-trivial objects within, will be
+ // destroyed with the pool.
+ template <typename... T>
+ internal::FlatAllocator::Allocation* CreateFlatAlloc(
+ const TypeMap<IntT, T...>& sizes);
+
+
+ private:
+ // All memory allocated in the pool. Must be first as other objects can
+ // point into these.
+ struct MiscDeleter {
+ void operator()(int* p) const { internal::SizedDelete(p, *p + 8); }
+ };
+ // Miscellaneous allocations are length prefixed. The paylaod is 8 bytes after
+ // the `int` that contains the size. This keeps the payload aligned.
+ std::vector<std::unique_ptr<int, MiscDeleter>> misc_allocs_;
+ struct FlatAllocDeleter {
+ void operator()(internal::FlatAllocator::Allocation* p) const {
+ p->Destroy();
+ }
+ };
+ std::vector<
+ std::unique_ptr<internal::FlatAllocator::Allocation, FlatAllocDeleter>>
+ flat_allocs_;
+
+ SymbolsByNameSet symbols_by_name_;
+ FilesByNameMap files_by_name_;
+ ExtensionsGroupedByDescriptorMap extensions_;
+
+ struct CheckPoint {
+ explicit CheckPoint(const Tables* tables)
+ : flat_allocations_before_checkpoint(
+ static_cast<int>(tables->flat_allocs_.size())),
+ misc_allocations_before_checkpoint(
+ static_cast<int>(tables->misc_allocs_.size())),
+ 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 flat_allocations_before_checkpoint;
+ int misc_allocations_before_checkpoint;
+ int pending_symbols_before_checkpoint;
+ int pending_files_before_checkpoint;
+ int pending_extensions_before_checkpoint;
+ };
+ std::vector<CheckPoint> checkpoints_;
+ std::vector<Symbol> symbols_after_checkpoint_;
+ std::vector<const FileDescriptor*> files_after_checkpoint_;
+ std::vector<DescriptorIntPair> extensions_after_checkpoint_;
+};
+
+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() {}
+
+FileDescriptorTables::~FileDescriptorTables() {
+ delete fields_by_lowercase_name_.load(std::memory_order_acquire);
+ delete fields_by_camelcase_name_.load(std::memory_order_acquire);
+}
+
+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();
+ }
+}
+
+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++) {
+ symbols_by_name_.erase(symbols_after_checkpoint_[i]);
+ }
+ for (size_t i = checkpoint.pending_files_before_checkpoint;
+ i < files_after_checkpoint_.size(); i++) {
+ files_by_name_.erase(files_after_checkpoint_[i]->name());
+ }
+ 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);
+
+ flat_allocs_.resize(checkpoint.flat_allocations_before_checkpoint);
+ misc_allocs_.resize(checkpoint.misc_allocations_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(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(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(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 {
+ auto* map = new FieldsByNameMap;
+ for (Symbol symbol : symbols_by_parent_) {
+ const FieldDescriptor* field = symbol.field_descriptor();
+ if (!field) continue;
+ (*map)[{FindParentForFieldsByMap(field), field->lowercase_name().c_str()}] =
+ field;
+ }
+ fields_by_lowercase_name_.store(map, std::memory_order_release);
+}
+
+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_.load(std::memory_order_acquire),
+ PointerStringPair(parent, lowercase_name));
+}
+
+void FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic(
+ const FileDescriptorTables* tables) {
+ tables->FieldsByCamelcaseNamesLazyInitInternal();
+}
+
+void FileDescriptorTables::FieldsByCamelcaseNamesLazyInitInternal() const {
+ auto* map = new FieldsByNameMap;
+ for (Symbol symbol : symbols_by_parent_) {
+ const FieldDescriptor* field = symbol.field_descriptor();
+ if (!field) continue;
+ (*map)[{FindParentForFieldsByMap(field), field->camelcase_name().c_str()}] =
+ field;
+ }
+ fields_by_camelcase_name_.store(map, std::memory_order_release);
+}
+
+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_.load(std::memory_order_acquire),
+ 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<int64_t>(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(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(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(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.
+ std::string 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());
+ internal::FlatAllocator alloc;
+ alloc.PlanArray<EnumValueDescriptor>(1);
+ alloc.PlanArray<std::string>(2);
+
+ {
+ // Must lock the pool because we will do allocations in the shared arena.
+ MutexLockMaybe l2(pool->mutex_);
+ alloc.FinalizePlanning(tables);
+ }
+ EnumValueDescriptor* result = alloc.AllocateArray<EnumValueDescriptor>(1);
+ result->all_names_ = alloc.AllocateStrings(
+ 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 std::string& full_name,
+ Symbol symbol) {
+ GOOGLE_DCHECK_EQ(full_name, symbol.full_name());
+ if (symbols_by_name_.insert(symbol).second) {
+ symbols_after_checkpoint_.push_back(symbol);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool FileDescriptorTables::AddAliasUnderParent(const void* parent,
+ const std::string& 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);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void FileDescriptorTables::FinalizeTables() {}
+
+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<int64_t>(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() {
+ static_assert(std::is_trivially_destructible<Type>::value, "");
+ static_assert(alignof(Type) <= 8, "");
+ return ::new (AllocateBytes(sizeof(Type))) Type{};
+}
+
+void* DescriptorPool::Tables::AllocateBytes(int size) {
+ if (size == 0) return nullptr;
+ void* p = ::operator new(size + RoundUpTo<8>(sizeof(int)));
+ int* sizep = static_cast<int*>(p);
+ misc_allocs_.emplace_back(sizep);
+ *sizep = size;
+ return static_cast<char*>(p) + RoundUpTo<8>(sizeof(int));
+}
+
+template <typename... T>
+internal::FlatAllocator::Allocation* DescriptorPool::Tables::CreateFlatAlloc(
+ const TypeMap<IntT, T...>& sizes) {
+ auto ends = CalculateEnds(sizes);
+ using FlatAlloc = internal::FlatAllocator::Allocation;
+
+ int last_end = ends.template Get<
+ typename std::tuple_element<sizeof...(T) - 1, std::tuple<T...>>::type>();
+ size_t total_size =
+ last_end + RoundUpTo<FlatAlloc::kMaxAlign>(sizeof(FlatAlloc));
+ char* data = static_cast<char*>(::operator new(total_size));
+ auto* res = ::new (data) FlatAlloc(ends);
+ flat_allocs_.emplace_back(res);
+
+ return res;
+}
+
+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_[std::string(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 = std::string(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 = std::string(name);
+ for (;;) {
+ std::string::size_type dot_pos = prefix.find_last_of('.');
+ if (dot_pos == std::string::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.IsPackage()) {
+ 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 = std::string(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();
+}
+
+std::string 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_int32_t());
+ case CPPTYPE_INT64:
+ return StrCat(default_value_int64_t());
+ case CPPTYPE_UINT32:
+ return StrCat(default_value_uint32_t());
+ case CPPTYPE_UINT64:
+ return StrCat(default_value_uint64_t());
+ 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<std::string>* 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++) {
+ std::string fieldval;
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ std::string 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);
+ }
+ std::string 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<std::string>* 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());
+ std::string 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, std::string* output) {
+ std::vector<std::string> 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, std::string* output) {
+ std::string prefix(depth * 2, ' ');
+ std::vector<std::string> all_options;
+ if (RetrieveOptions(depth, options, pool, &all_options)) {
+ for (const std::string& 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 std::string& 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 std::string& 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(std::string* output) {
+ if (have_source_loc_) {
+ // Detached leading comments.
+ for (const std::string& 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(std::string* 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.
+ std::string FormatComment(const std::string& comment_text) {
+ std::string stripped_comment = comment_text;
+ StripWhitespace(&stripped_comment);
+ std::vector<std::string> lines = Split(stripped_comment, "\n");
+ std::string output;
+ for (const std::string& line : lines) {
+ strings::SubstituteAndAppend(&output, "$0// $1\n", prefix_, line);
+ }
+ return output;
+ }
+
+ private:
+
+ bool have_source_loc_;
+ SourceLocation source_loc_;
+ DebugStringOptions options_;
+ std::string prefix_;
+};
+
+} // anonymous namespace
+
+std::string FileDescriptor::DebugString() const {
+ DebugStringOptions options; // default options
+ return DebugStringWithOptions(options);
+}
+
+std::string FileDescriptor::DebugStringWithOptions(
+ const DebugStringOptions& debug_string_options) const {
+ std::string 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;
+}
+
+std::string Descriptor::DebugString() const {
+ DebugStringOptions options; // default options
+ return DebugStringWithOptions(options);
+}
+
+std::string Descriptor::DebugStringWithOptions(
+ const DebugStringOptions& options) const {
+ std::string contents;
+ DebugString(0, &contents, options, /* include_opening_clause */ true);
+ return contents;
+}
+
+void Descriptor::DebugString(int depth, std::string* 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;
+ }
+ std::string 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);
+}
+
+std::string FieldDescriptor::DebugString() const {
+ DebugStringOptions options; // default options
+ return DebugStringWithOptions(options);
+}
+
+std::string FieldDescriptor::DebugStringWithOptions(
+ const DebugStringOptions& debug_string_options) const {
+ std::string 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()
+std::string 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, std::string* contents,
+ const DebugStringOptions& debug_string_options) const {
+ std::string prefix(depth * 2, ' ');
+ std::string 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();
+ }
+
+ std::string 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("\"");
+ }
+
+ std::string 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);
+}
+
+std::string OneofDescriptor::DebugString() const {
+ DebugStringOptions options; // default values
+ return DebugStringWithOptions(options);
+}
+
+std::string OneofDescriptor::DebugStringWithOptions(
+ const DebugStringOptions& options) const {
+ std::string contents;
+ DebugString(0, &contents, options);
+ return contents;
+}
+
+void OneofDescriptor::DebugString(
+ int depth, std::string* contents,
+ const DebugStringOptions& debug_string_options) const {
+ std::string 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);
+}
+
+std::string EnumDescriptor::DebugString() const {
+ DebugStringOptions options; // default values
+ return DebugStringWithOptions(options);
+}
+
+std::string EnumDescriptor::DebugStringWithOptions(
+ const DebugStringOptions& options) const {
+ std::string contents;
+ DebugString(0, &contents, options);
+ return contents;
+}
+
+void EnumDescriptor::DebugString(
+ int depth, std::string* contents,
+ const DebugStringOptions& debug_string_options) const {
+ std::string 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);
+}
+
+std::string EnumValueDescriptor::DebugString() const {
+ DebugStringOptions options; // default values
+ return DebugStringWithOptions(options);
+}
+
+std::string EnumValueDescriptor::DebugStringWithOptions(
+ const DebugStringOptions& options) const {
+ std::string contents;
+ DebugString(0, &contents, options);
+ return contents;
+}
+
+void EnumValueDescriptor::DebugString(
+ int depth, std::string* contents,
+ const DebugStringOptions& debug_string_options) const {
+ std::string prefix(depth * 2, ' ');
+
+ SourceLocationCommentPrinter comment_printer(this, prefix,
+ debug_string_options);
+ comment_printer.AddPreComment(contents);
+
+ strings::SubstituteAndAppend(contents, "$0$1 = $2", prefix, name(), number());
+
+ std::string formatted_options;
+ if (FormatBracketedOptions(depth, options(), type()->file()->pool(),
+ &formatted_options)) {
+ strings::SubstituteAndAppend(contents, " [$0]", formatted_options);
+ }
+ contents->append(";\n");
+
+ comment_printer.AddPostComment(contents);
+}
+
+std::string ServiceDescriptor::DebugString() const {
+ DebugStringOptions options; // default values
+ return DebugStringWithOptions(options);
+}
+
+std::string ServiceDescriptor::DebugStringWithOptions(
+ const DebugStringOptions& options) const {
+ std::string contents;
+ DebugString(&contents, options);
+ return contents;
+}
+
+void ServiceDescriptor::DebugString(
+ std::string* 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);
+}
+
+std::string MethodDescriptor::DebugString() const {
+ DebugStringOptions options; // default values
+ return DebugStringWithOptions(options);
+}
+
+std::string MethodDescriptor::DebugStringWithOptions(
+ const DebugStringOptions& options) const {
+ std::string contents;
+ DebugString(0, &contents, options);
+ return contents;
+}
+
+void MethodDescriptor::DebugString(
+ int depth, std::string* contents,
+ const DebugStringOptions& debug_string_options) const {
+ std::string 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 " : "");
+
+ std::string 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<int32_t>& 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 std::string& ns, const std::string& 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) {}
+ std::string name_scope;
+ std::string 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,
+ internal::FlatAllocator& alloc);
+
+ 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_;
+ std::string filename_;
+ FileDescriptor* file_;
+ FileDescriptorTables* file_tables_;
+ std::set<const FileDescriptor*> dependencies_;
+
+ struct MessageHints {
+ int fields_to_suggest = 0;
+ const Message* first_reason = nullptr;
+ DescriptorPool::ErrorCollector::ErrorLocation first_reason_location =
+ DescriptorPool::ErrorCollector::ErrorLocation::OTHER;
+
+ void RequestHintOnFieldNumbers(
+ const Message& reason,
+ DescriptorPool::ErrorCollector::ErrorLocation reason_location,
+ int range_start = 0, int range_end = 1) {
+ auto fit = [](int value) {
+ return std::min(std::max(value, 0), FieldDescriptor::kMaxNumber);
+ };
+ fields_to_suggest =
+ fit(fields_to_suggest + fit(fit(range_end) - fit(range_start)));
+ if (first_reason) return;
+ first_reason = &reason;
+ first_reason_location = reason_location;
+ }
+ };
+
+ std::unordered_map<const Descriptor*, MessageHints> message_hints_;
+
+ // 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_;
+ std::string 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.
+ std::string undefine_resolved_name_;
+
+ // Tracker for current recursion depth to implement recursion protection.
+ //
+ // Counts down to 0 when there is no depth remaining.
+ //
+ // Maximum recursion depth corresponds to 32 nested message declarations.
+ int recursion_depth_ = 32;
+
+ void AddError(const std::string& element_name, const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const std::string& error);
+ void AddError(const std::string& 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 std::string& element_name, const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const std::string& undefined_symbol);
+
+ void AddWarning(const std::string& element_name, const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const std::string& 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 std::string& 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 std::string& 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 std::string& name,
+ bool build_it = true);
+
+ // This implements the body of FindSymbolNotEnforcingDeps().
+ Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool,
+ const std::string& 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.moo.corge") makes
+ // the following calls, returning the first non-null result:
+ // FindSymbol("baz.moo.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 std::string& name, const std::string& 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 std::string& name,
+ const std::string& 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 std::string& full_name, const void* parent,
+ const std::string& 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 std::string& name, const Message& proto,
+ FileDescriptor* file);
+
+ // Checks that the symbol name contains only alphanumeric characters and
+ // underscores. Records an error otherwise.
+ void ValidateSymbolName(const std::string& name, const std::string& full_name,
+ const Message& proto);
+
+ // 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 std::string& option_name,
+ internal::FlatAllocator& alloc);
+ // Specialization for FileOptions.
+ void AllocateOptions(const FileOptions& orig_options,
+ FileDescriptor* descriptor,
+ internal::FlatAllocator& alloc);
+
+ // Implementation for AllocateOptions(). Don't call this directly.
+ template <class DescriptorT>
+ void AllocateOptionsImpl(
+ const std::string& name_scope, const std::string& element_name,
+ const typename DescriptorT::OptionsType& orig_options,
+ DescriptorT* descriptor, const std::vector<int>& options_path,
+ const std::string& option_name, internal::FlatAllocator& alloc);
+
+ // 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 std::string* AllocateNameStrings(const std::string& scope,
+ const std::string& proto_name,
+ internal::FlatAllocator& alloc);
+
+ // 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, internal::FlatAllocator& alloc);
+ void BuildFieldOrExtension(const FieldDescriptorProto& proto,
+ Descriptor* parent, FieldDescriptor* result,
+ bool is_extension, internal::FlatAllocator& alloc);
+ void BuildField(const FieldDescriptorProto& proto, Descriptor* parent,
+ FieldDescriptor* result, internal::FlatAllocator& alloc) {
+ BuildFieldOrExtension(proto, parent, result, false, alloc);
+ }
+ void BuildExtension(const FieldDescriptorProto& proto, Descriptor* parent,
+ FieldDescriptor* result, internal::FlatAllocator& alloc) {
+ BuildFieldOrExtension(proto, parent, result, true, alloc);
+ }
+ void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto,
+ const Descriptor* parent,
+ Descriptor::ExtensionRange* result,
+ internal::FlatAllocator& alloc);
+ void BuildReservedRange(const DescriptorProto::ReservedRange& proto,
+ const Descriptor* parent,
+ Descriptor::ReservedRange* result,
+ internal::FlatAllocator& alloc);
+ void BuildReservedRange(const EnumDescriptorProto::EnumReservedRange& proto,
+ const EnumDescriptor* parent,
+ EnumDescriptor::ReservedRange* result,
+ internal::FlatAllocator& alloc);
+ void BuildOneof(const OneofDescriptorProto& proto, Descriptor* parent,
+ OneofDescriptor* result, internal::FlatAllocator& alloc);
+ void CheckEnumValueUniqueness(const EnumDescriptorProto& proto,
+ const EnumDescriptor* result);
+ void BuildEnum(const EnumDescriptorProto& proto, const Descriptor* parent,
+ EnumDescriptor* result, internal::FlatAllocator& alloc);
+ void BuildEnumValue(const EnumValueDescriptorProto& proto,
+ const EnumDescriptor* parent, EnumValueDescriptor* result,
+ internal::FlatAllocator& alloc);
+ void BuildService(const ServiceDescriptorProto& proto, const void* dummy,
+ ServiceDescriptor* result, internal::FlatAllocator& alloc);
+ void BuildMethod(const MethodDescriptorProto& proto,
+ const ServiceDescriptor* parent, MethodDescriptor* result,
+ internal::FlatAllocator& alloc);
+
+ 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);
+ void SuggestFieldNumbers(FileDescriptor* file,
+ const FileDescriptorProto& 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 std::string& 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, int32_t value, FieldDescriptor::Type type,
+ UnknownFieldSet* unknown_fields);
+ void SetInt64(int number, int64_t value, FieldDescriptor::Type type,
+ UnknownFieldSet* unknown_fields);
+ void SetUInt32(int number, uint32_t value, FieldDescriptor::Type type,
+ UnknownFieldSet* unknown_fields);
+ void SetUInt64(int number, uint64_t 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 std::string& 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 std::string& 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 std::string& 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 std::string& 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 std::string& element_name, const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const std::string& 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 std::string& element_name, const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location, const char* error) {
+ AddError(element_name, descriptor, location, std::string(error));
+}
+
+void DescriptorBuilder::AddNotDefinedError(
+ const std::string& element_name, const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const std::string& 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 std::string& element_name, const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const std::string& 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 std::string& 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 std::string& 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 std::string& 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 std::string& 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.IsPackage()) {
+ // 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 std::string& name, const std::string& 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.
+ std::string::size_type name_dot_pos = name.find_first_of('.');
+ std::string first_part_of_name;
+ if (name_dot_pos == std::string::npos) {
+ first_part_of_name = name;
+ } else {
+ first_part_of_name = name.substr(0, name_dot_pos);
+ }
+
+ std::string scope_to_try(relative_to);
+
+ while (true) {
+ // Chop off the last component of the scope.
+ std::string::size_type dot_pos = scope_to_try.find_last_of('.');
+ if (dot_pos == std::string::npos) {
+ return FindSymbol(name, build_it);
+ } else {
+ scope_to_try.erase(dot_pos);
+ }
+
+ // Append ".first_part_of_name" and try to find.
+ std::string::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 std::string& name, const std::string& 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 std::string* placeholder_package;
+
+ if (!ValidateQualifiedName(name)) return Symbol();
+ if (name[0] == '.') {
+ // Fully-qualified.
+ placeholder_full_name = name.substr(1);
+ } else {
+ placeholder_full_name = name;
+ }
+
+ // Create the placeholders.
+ internal::FlatAllocator alloc;
+ alloc.PlanArray<FileDescriptor>(1);
+ alloc.PlanArray<std::string>(2);
+ if (placeholder_type == PLACEHOLDER_ENUM) {
+ alloc.PlanArray<EnumDescriptor>(1);
+ alloc.PlanArray<EnumValueDescriptor>(1);
+ alloc.PlanArray<std::string>(2); // names for the descriptor.
+ alloc.PlanArray<std::string>(2); // names for the value.
+ } else {
+ alloc.PlanArray<Descriptor>(1);
+ alloc.PlanArray<std::string>(2); // names for the descriptor.
+ if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) {
+ alloc.PlanArray<Descriptor::ExtensionRange>(1);
+ }
+ }
+ alloc.FinalizePlanning(tables_);
+
+ const std::string::size_type dotpos = placeholder_full_name.find_last_of('.');
+ if (dotpos != std::string::npos) {
+ placeholder_package =
+ alloc.AllocateStrings(placeholder_full_name.substr(0, dotpos));
+ placeholder_name = placeholder_full_name.substr(dotpos + 1);
+ } else {
+ placeholder_package = alloc.AllocateStrings("");
+ placeholder_name = placeholder_full_name;
+ }
+
+ FileDescriptor* placeholder_file = NewPlaceholderFileWithMutexHeld(
+ StrCat(placeholder_full_name, ".placeholder.proto"), alloc);
+ placeholder_file->package_ = placeholder_package;
+
+ if (placeholder_type == PLACEHOLDER_ENUM) {
+ placeholder_file->enum_type_count_ = 1;
+ placeholder_file->enum_types_ = alloc.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_ =
+ alloc.AllocateStrings(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_ = alloc.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_ = alloc.AllocateStrings(
+ "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_ = alloc.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_ =
+ alloc.AllocateStrings(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_ =
+ alloc.AllocateArray<Descriptor::ExtensionRange>(1);
+ placeholder_message->extension_ranges_[0].start = 1;
+ // kMaxNumber + 1 because ExtensionRange::end is exclusive.
+ placeholder_message->extension_ranges_[0].end =
+ FieldDescriptor::kMaxNumber + 1;
+ placeholder_message->extension_ranges_[0].options_ = nullptr;
+ }
+
+ return Symbol(placeholder_message);
+ }
+}
+
+FileDescriptor* DescriptorPool::NewPlaceholderFile(
+ StringPiece name) const {
+ MutexLockMaybe lock(mutex_);
+ internal::FlatAllocator alloc;
+ alloc.PlanArray<FileDescriptor>(1);
+ alloc.PlanArray<std::string>(1);
+ alloc.FinalizePlanning(tables_);
+
+ return NewPlaceholderFileWithMutexHeld(name, alloc);
+}
+
+FileDescriptor* DescriptorPool::NewPlaceholderFileWithMutexHeld(
+ StringPiece name, internal::FlatAllocator& alloc) const {
+ if (mutex_) {
+ mutex_->AssertHeld();
+ }
+ FileDescriptor* placeholder = alloc.AllocateArray<FileDescriptor>(1);
+ memset(static_cast<void*>(placeholder), 0, sizeof(*placeholder));
+
+ placeholder->name_ = alloc.AllocateStrings(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 std::string& full_name,
+ const void* parent, const std::string& 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') != std::string::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_) {
+ std::string::size_type dot_pos = full_name.find_last_of('.');
+ if (dot_pos == std::string::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 std::string& name,
+ const Message& proto, FileDescriptor* file) {
+ if (name.find('\0') != std::string::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()) {
+ if (&name == &file->package()) {
+ // It is the toplevel package name, so insert the descriptor directly.
+ tables_->AddSymbol(file->package(), Symbol(file));
+ } else {
+ auto* package = tables_->Allocate<Symbol::Subpackage>();
+ // 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_size = static_cast<int>(name.size());
+ package->file = file;
+ tables_->AddSymbol(name, Symbol(package));
+ }
+ // Also add parent package, if any.
+ std::string::size_type dot_pos = name.find_last_of('.');
+ if (dot_pos == std::string::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.IsPackage()) {
+ // Symbol seems to have been defined in a different file.
+ const FileDescriptor* other_file = existing_symbol.GetFile();
+ AddError(name, proto, DescriptorPool::ErrorCollector::NAME,
+ "\"" + name +
+ "\" is already defined (as something other than "
+ "a package) in file \"" +
+ (other_file == nullptr ? "null" : other_file->name()) + "\".");
+ }
+}
+
+void DescriptorBuilder::ValidateSymbolName(const std::string& name,
+ const std::string& 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.");
+ return;
+ }
+ }
+ }
+}
+
+// -------------------------------------------------------------------
+
+// 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 std::string& option_name, internal::FlatAllocator& alloc) {
+ 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,
+ alloc);
+}
+
+// We specialize for FileDescriptor.
+void DescriptorBuilder::AllocateOptions(const FileOptions& orig_options,
+ FileDescriptor* descriptor,
+ internal::FlatAllocator& alloc) {
+ 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", alloc);
+}
+
+template <class DescriptorT>
+void DescriptorBuilder::AllocateOptionsImpl(
+ const std::string& name_scope, const std::string& element_name,
+ const typename DescriptorT::OptionsType& orig_options,
+ DescriptorT* descriptor, const std::vector<int>& options_path,
+ const std::string& option_name, internal::FlatAllocator& alloc) {
+ auto* options = alloc.AllocateArray<typename DescriptorT::OptionsType>(1);
+
+ 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(); \
+ OUTPUT->NAME##s_ = alloc.AllocateArray< \
+ typename std::remove_pointer<decltype(OUTPUT->NAME##s_)>::type>( \
+ INPUT.NAME##_size()); \
+ for (int i = 0; i < INPUT.NAME##_size(); i++) { \
+ METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i, alloc); \
+ }
+
+void DescriptorBuilder::AddRecursiveImportError(
+ const FileDescriptorProto& proto, int from_here) {
+ std::string 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) {
+ std::string 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();
+}
+
+// These PlanAllocationSize functions will gather into the FlatAllocator all the
+// necessary memory allocations that BuildXXX functions below will do on the
+// Tables object.
+// They *must* be kept in sync. If we miss some PlanArray call we won't have
+// enough memory and will GOOGLE_CHECK-fail.
+static void PlanAllocationSize(
+ const RepeatedPtrField<EnumValueDescriptorProto>& values,
+ internal::FlatAllocator& alloc) {
+ alloc.PlanArray<EnumValueDescriptor>(values.size());
+ alloc.PlanArray<std::string>(2 * values.size()); // name + full_name
+ for (const auto& v : values) {
+ if (v.has_options()) alloc.PlanArray<EnumValueOptions>(1);
+ }
+}
+
+static void PlanAllocationSize(
+ const RepeatedPtrField<EnumDescriptorProto>& enums,
+ internal::FlatAllocator& alloc) {
+ alloc.PlanArray<EnumDescriptor>(enums.size());
+ alloc.PlanArray<std::string>(2 * enums.size()); // name + full_name
+ for (const auto& e : enums) {
+ if (e.has_options()) alloc.PlanArray<EnumOptions>(1);
+ PlanAllocationSize(e.value(), alloc);
+ alloc.PlanArray<EnumDescriptor::ReservedRange>(e.reserved_range_size());
+ alloc.PlanArray<const std::string*>(e.reserved_name_size());
+ alloc.PlanArray<std::string>(e.reserved_name_size());
+ }
+}
+
+static void PlanAllocationSize(
+ const RepeatedPtrField<OneofDescriptorProto>& oneofs,
+ internal::FlatAllocator& alloc) {
+ alloc.PlanArray<OneofDescriptor>(oneofs.size());
+ alloc.PlanArray<std::string>(2 * oneofs.size()); // name + full_name
+ for (const auto& oneof : oneofs) {
+ if (oneof.has_options()) alloc.PlanArray<OneofOptions>(1);
+ }
+}
+
+static void PlanAllocationSize(
+ const RepeatedPtrField<FieldDescriptorProto>& fields,
+ internal::FlatAllocator& alloc) {
+ alloc.PlanArray<FieldDescriptor>(fields.size());
+ for (const auto& field : fields) {
+ if (field.has_options()) alloc.PlanArray<FieldOptions>(1);
+ alloc.PlanFieldNames(field.name(),
+ field.has_json_name() ? &field.json_name() : nullptr);
+ if (field.has_default_value() && field.has_type() &&
+ (field.type() == FieldDescriptorProto::TYPE_STRING ||
+ field.type() == FieldDescriptorProto::TYPE_BYTES)) {
+ // For the default string value.
+ alloc.PlanArray<std::string>(1);
+ }
+ }
+}
+
+static void PlanAllocationSize(
+ const RepeatedPtrField<DescriptorProto::ExtensionRange>& ranges,
+ internal::FlatAllocator& alloc) {
+ alloc.PlanArray<Descriptor::ExtensionRange>(ranges.size());
+ for (const auto& r : ranges) {
+ if (r.has_options()) alloc.PlanArray<ExtensionRangeOptions>(1);
+ }
+}
+
+static void PlanAllocationSize(
+ const RepeatedPtrField<DescriptorProto>& messages,
+ internal::FlatAllocator& alloc) {
+ alloc.PlanArray<Descriptor>(messages.size());
+ alloc.PlanArray<std::string>(2 * messages.size()); // name + full_name
+
+ for (const auto& message : messages) {
+ if (message.has_options()) alloc.PlanArray<MessageOptions>(1);
+ PlanAllocationSize(message.nested_type(), alloc);
+ PlanAllocationSize(message.field(), alloc);
+ PlanAllocationSize(message.extension(), alloc);
+ PlanAllocationSize(message.extension_range(), alloc);
+ alloc.PlanArray<Descriptor::ReservedRange>(message.reserved_range_size());
+ alloc.PlanArray<const std::string*>(message.reserved_name_size());
+ alloc.PlanArray<std::string>(message.reserved_name_size());
+ PlanAllocationSize(message.enum_type(), alloc);
+ PlanAllocationSize(message.oneof_decl(), alloc);
+ }
+}
+
+static void PlanAllocationSize(
+ const RepeatedPtrField<MethodDescriptorProto>& methods,
+ internal::FlatAllocator& alloc) {
+ alloc.PlanArray<MethodDescriptor>(methods.size());
+ alloc.PlanArray<std::string>(2 * methods.size()); // name + full_name
+ for (const auto& m : methods) {
+ if (m.has_options()) alloc.PlanArray<MethodOptions>(1);
+ }
+}
+
+static void PlanAllocationSize(
+ const RepeatedPtrField<ServiceDescriptorProto>& services,
+ internal::FlatAllocator& alloc) {
+ alloc.PlanArray<ServiceDescriptor>(services.size());
+ alloc.PlanArray<std::string>(2 * services.size()); // name + full_name
+ for (const auto& service : services) {
+ if (service.has_options()) alloc.PlanArray<ServiceOptions>(1);
+ PlanAllocationSize(service.method(), alloc);
+ }
+}
+
+static void PlanAllocationSize(const FileDescriptorProto& proto,
+ internal::FlatAllocator& alloc) {
+ alloc.PlanArray<FileDescriptor>(1);
+ alloc.PlanArray<FileDescriptorTables>(1);
+ alloc.PlanArray<std::string>(2); // name + package
+ if (proto.has_options()) alloc.PlanArray<FileOptions>(1);
+ if (proto.has_source_code_info()) alloc.PlanArray<SourceCodeInfo>(1);
+
+ PlanAllocationSize(proto.service(), alloc);
+ PlanAllocationSize(proto.message_type(), alloc);
+ PlanAllocationSize(proto.enum_type(), alloc);
+ PlanAllocationSize(proto.extension(), alloc);
+
+ alloc.PlanArray<int>(proto.weak_dependency_size());
+ alloc.PlanArray<int>(proto.public_dependency_size());
+ alloc.PlanArray<const FileDescriptor*>(proto.dependency_size());
+}
+
+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;
+ }
+ }
+
+ static const int kMaximumPackageLength = 511;
+ if (proto.package().size() > kMaximumPackageLength) {
+ AddError(proto.package(), proto, DescriptorPool::ErrorCollector::NAME,
+ "Package name is too long");
+ 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();
+
+ internal::FlatAllocator alloc;
+ PlanAllocationSize(proto, alloc);
+ alloc.FinalizePlanning(tables_);
+ FileDescriptor* result = BuildFileImpl(proto, alloc);
+
+ file_tables_->FinalizeTables();
+ if (result) {
+ tables_->ClearLastCheckpoint();
+ result->finished_building_ = true;
+ alloc.ExpectConsumed();
+ } else {
+ tables_->RollbackToLastCheckpoint();
+ }
+
+ return result;
+}
+
+FileDescriptor* DescriptorBuilder::BuildFileImpl(
+ const FileDescriptorProto& proto, internal::FlatAllocator& alloc) {
+ FileDescriptor* result = alloc.AllocateArray<FileDescriptor>(1);
+ file_ = result;
+
+ result->is_placeholder_ = false;
+ result->finished_building_ = false;
+ SourceCodeInfo* info = nullptr;
+ if (proto.has_source_code_info()) {
+ info = alloc.AllocateArray<SourceCodeInfo>(1);
+ info->CopyFrom(proto.source_code_info());
+ result->source_code_info_ = info;
+ } else {
+ result->source_code_info_ = &SourceCodeInfo::default_instance();
+ }
+
+ file_tables_ = alloc.AllocateArray<FileDescriptorTables>(1);
+ 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_ = alloc.AllocateStrings(proto.name());
+ if (proto.has_package()) {
+ result->package_ = alloc.AllocateStrings(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_ = alloc.AllocateStrings("");
+ }
+ result->pool_ = pool_;
+
+ if (result->name().find('\0') != std::string::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()) {
+ if (std::count(result->package().begin(), result->package().end(), '.') >
+ kPackageLimit) {
+ AddError(result->package(), proto, DescriptorPool::ErrorCollector::NAME,
+ "Exceeds Maximum Package Depth");
+ return nullptr;
+ }
+ AddPackage(result->package(), proto, result);
+ }
+
+ // Make sure all dependencies are loaded.
+ std::set<std::string> seen_dependencies;
+ result->dependency_count_ = proto.dependency_size();
+ result->dependencies_ =
+ alloc.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));
+ }
+
+ bool need_lazy_deps = false;
+ 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())) {
+ internal::FlatAllocator lazy_dep_alloc;
+ lazy_dep_alloc.PlanArray<FileDescriptor>(1);
+ lazy_dep_alloc.PlanArray<std::string>(1);
+ lazy_dep_alloc.FinalizePlanning(tables_);
+ dependency = pool_->NewPlaceholderFileWithMutexHeld(
+ proto.dependency(i), lazy_dep_alloc);
+ } 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) {
+ need_lazy_deps = true;
+ }
+ }
+ if (need_lazy_deps) {
+ int total_char_size = 0;
+ for (int i = 0; i < proto.dependency_size(); i++) {
+ if (result->dependencies_[i] == nullptr) {
+ total_char_size += static_cast<int>(proto.dependency(i).size());
+ }
+ ++total_char_size; // For NUL char
+ }
+
+ void* data = tables_->AllocateBytes(
+ static_cast<int>(sizeof(internal::once_flag) + total_char_size));
+ result->dependencies_once_ = ::new (data) internal::once_flag{};
+ char* name_data = reinterpret_cast<char*>(result->dependencies_once_ + 1);
+
+ for (int i = 0; i < proto.dependency_size(); i++) {
+ if (result->dependencies_[i] == nullptr) {
+ memcpy(name_data, proto.dependency(i).c_str(),
+ proto.dependency(i).size());
+ name_data += proto.dependency(i).size();
+ }
+ *name_data++ = '\0';
+ }
+ }
+
+ // Check public dependencies.
+ int public_dependency_count = 0;
+ result->public_dependencies_ =
+ alloc.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_ =
+ alloc.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, alloc);
+ }
+
+ // Note that the following steps must occur in exactly the specified order.
+
+ // Cross-link.
+ CrossLinkFile(result, proto);
+
+ if (!message_hints_.empty()) {
+ SuggestFieldNumbers(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 std::string* DescriptorBuilder::AllocateNameStrings(
+ const std::string& scope, const std::string& proto_name,
+ internal::FlatAllocator& alloc) {
+ if (scope.empty()) {
+ return alloc.AllocateStrings(proto_name, proto_name);
+ } else {
+ return alloc.AllocateStrings(proto_name,
+ StrCat(scope, ".", proto_name));
+ }
+}
+
+namespace {
+
+// Helper for BuildMessage below.
+struct IncrementWhenDestroyed {
+ ~IncrementWhenDestroyed() { ++to_increment; }
+ int& to_increment;
+};
+
+} // namespace
+
+void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
+ const Descriptor* parent,
+ Descriptor* result,
+ internal::FlatAllocator& alloc) {
+ const std::string& scope =
+ (parent == nullptr) ? file_->package() : parent->full_name();
+ result->all_names_ = AllocateNameStrings(scope, proto.name(), alloc);
+ 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;
+ result->options_ = nullptr; // Set to default_instance later if necessary.
+
+ 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, 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);
+
+ // Before building submessages, check recursion limit.
+ --recursion_depth_;
+ IncrementWhenDestroyed revert{recursion_depth_};
+ if (recursion_depth_ <= 0) {
+ AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::OTHER,
+ "Reached maximum recursion limit for nested messages.");
+ result->nested_types_ = nullptr;
+ result->nested_type_count_ = 0;
+ return;
+ }
+ BUILD_ARRAY(proto, result, nested_type, BuildMessage, result);
+
+ // Copy reserved names.
+ int reserved_name_count = proto.reserved_name_size();
+ result->reserved_name_count_ = reserved_name_count;
+ result->reserved_names_ =
+ alloc.AllocateArray<const std::string*>(reserved_name_count);
+ for (int i = 0; i < reserved_name_count; ++i) {
+ result->reserved_names_[i] =
+ alloc.AllocateStrings(proto.reserved_name(i));
+ }
+
+ // Copy options.
+ if (proto.has_options()) {
+ AllocateOptions(proto.options(), result,
+ DescriptorProto::kOptionsFieldNumber,
+ "google.protobuf.MessageOptions", alloc);
+ }
+
+ 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<std::string> reserved_name_set;
+ for (int i = 0; i < proto.reserved_name_size(); i++) {
+ const std::string& 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) {
+ message_hints_[result].RequestHintOnFieldNumbers(
+ proto.extension_range(j), DescriptorPool::ErrorCollector::NUMBER);
+ 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) {
+ message_hints_[result].RequestHintOnFieldNumbers(
+ proto.reserved_range(j), DescriptorPool::ErrorCollector::NUMBER);
+ 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,
+ internal::FlatAllocator& alloc) {
+ const std::string& 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 = alloc.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_int32_t_ =
+ strtol(proto.default_value().c_str(), &end_pos, 0);
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ result->default_value_int64_t_ =
+ strto64(proto.default_value().c_str(), &end_pos, 0);
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ result->default_value_uint32_t_ =
+ strtoul(proto.default_value().c_str(), &end_pos, 0);
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ result->default_value_uint64_t_ =
+ 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_ = alloc.AllocateStrings(
+ UnescapeCEscapeString(proto.default_value()));
+ } else {
+ result->default_value_string_ =
+ alloc.AllocateStrings(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_int32_t_ = 0;
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ result->default_value_int64_t_ = 0;
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ result->default_value_uint32_t_ = 0;
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ result->default_value_uint64_t_ = 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) {
+ message_hints_[parent].RequestHintOnFieldNumbers(
+ proto, DescriptorPool::ErrorCollector::NUMBER);
+ 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.
+ message_hints_[parent].RequestHintOnFieldNumbers(
+ proto, DescriptorPool::ErrorCollector::NUMBER);
+ 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) {
+ message_hints_[parent].RequestHintOnFieldNumbers(
+ proto, DescriptorPool::ErrorCollector::NUMBER);
+ 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", alloc);
+ }
+
+ AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
+}
+
+void DescriptorBuilder::BuildExtensionRange(
+ const DescriptorProto::ExtensionRange& proto, const Descriptor* parent,
+ Descriptor::ExtensionRange* result, internal::FlatAllocator& alloc) {
+ result->start = proto.start();
+ result->end = proto.end();
+ if (result->start <= 0) {
+ message_hints_[parent].RequestHintOnFieldNumbers(
+ proto, DescriptorPool::ErrorCollector::NUMBER, result->start,
+ result->end);
+ 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", alloc);
+ }
+}
+
+void DescriptorBuilder::BuildReservedRange(
+ const DescriptorProto::ReservedRange& proto, const Descriptor* parent,
+ Descriptor::ReservedRange* result, internal::FlatAllocator&) {
+ result->start = proto.start();
+ result->end = proto.end();
+ if (result->start <= 0) {
+ message_hints_[parent].RequestHintOnFieldNumbers(
+ proto, DescriptorPool::ErrorCollector::NUMBER, result->start,
+ result->end);
+ 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,
+ internal::FlatAllocator&) {
+ 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,
+ internal::FlatAllocator& alloc) {
+ result->all_names_ =
+ AllocateNameStrings(parent->full_name(), proto.name(), alloc);
+ 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", alloc);
+ }
+
+ 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<std::string, const EnumValueDescriptor*> values;
+ for (int i = 0; i < result->value_count(); i++) {
+ const EnumValueDescriptor* value = result->value(i);
+ std::string stripped =
+ EnumValueToPascalCase(remover.MaybeRemove(value->name()));
+ std::pair<std::map<std::string, 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()) {
+ std::string 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,
+ internal::FlatAllocator& alloc) {
+ const std::string& scope =
+ (parent == nullptr) ? file_->package() : parent->full_name();
+
+ result->all_names_ = AllocateNameStrings(scope, proto.name(), alloc);
+ 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 int64_t to avoid overflows.
+ proto.value(i).number() ==
+ static_cast<int64_t>(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_ =
+ alloc.AllocateArray<const std::string*>(reserved_name_count);
+ for (int i = 0; i < reserved_name_count; ++i) {
+ result->reserved_names_[i] =
+ alloc.AllocateStrings(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", alloc);
+ }
+
+ 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<std::string> reserved_name_set;
+ for (int i = 0; i < proto.reserved_name_size(); i++) {
+ const std::string& 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,
+ internal::FlatAllocator& alloc) {
+ // Note: full_name for enum values is a sibling to the parent's name, not a
+ // child of it.
+ std::string 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_ =
+ alloc.AllocateStrings(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", alloc);
+ }
+
+ // 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.
+ std::string 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,
+ internal::FlatAllocator& alloc) {
+ result->all_names_ =
+ AllocateNameStrings(file_->package(), proto.name(), alloc);
+ 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", alloc);
+ }
+
+ AddSymbol(result->full_name(), nullptr, result->name(), proto,
+ Symbol(result));
+}
+
+void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto,
+ const ServiceDescriptor* parent,
+ MethodDescriptor* result,
+ internal::FlatAllocator& alloc) {
+ result->service_ = parent;
+ result->all_names_ =
+ AllocateNameStrings(parent->full_name(), proto.name(), alloc);
+
+ 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", alloc);
+ }
+
+ 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();
+ }
+
+ 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.
+ const std::string& name = proto.type_name();
+
+ int name_sizes = static_cast<int>(name.size() + 1 +
+ proto.default_value().size() + 1);
+
+ field->type_once_ = ::new (tables_->AllocateBytes(static_cast<int>(
+ sizeof(internal::once_flag) + name_sizes))) internal::once_flag{};
+ char* names = reinterpret_cast<char*>(field->type_once_ + 1);
+
+ memcpy(names, name.c_str(), name.size() + 1);
+ memcpy(names + name.size() + 1, proto.default_value().c_str(),
+ proto.default_value().size() + 1);
+
+ // 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());
+ std::string 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());
+ std::string containing_type_name =
+ field->containing_type() == nullptr
+ ? "unknown"
+ : field->containing_type()->full_name();
+ std::string 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());
+ }
+}
+
+void DescriptorBuilder::SuggestFieldNumbers(FileDescriptor* file,
+ const FileDescriptorProto& proto) {
+ for (int message_index = 0; message_index < file->message_type_count();
+ message_index++) {
+ const Descriptor* message = &file->message_types_[message_index];
+ auto* hints = FindOrNull(message_hints_, message);
+ if (!hints) continue;
+ constexpr int kMaxSuggestions = 3;
+ int fields_to_suggest = std::min(kMaxSuggestions, hints->fields_to_suggest);
+ if (fields_to_suggest <= 0) continue;
+ struct Range {
+ int from;
+ int to;
+ };
+ std::vector<Range> used_ordinals;
+ auto add_ordinal = [&](int ordinal) {
+ if (ordinal <= 0 || ordinal > FieldDescriptor::kMaxNumber) return;
+ if (!used_ordinals.empty() &&
+ ordinal == used_ordinals.back().to) {
+ used_ordinals.back().to = ordinal + 1;
+ } else {
+ used_ordinals.push_back({ordinal, ordinal + 1});
+ }
+ };
+ auto add_range = [&](int from, int to) {
+ from = std::max(0, std::min(FieldDescriptor::kMaxNumber + 1, from));
+ to = std::max(0, std::min(FieldDescriptor::kMaxNumber + 1, to));
+ if (from >= to) return;
+ used_ordinals.push_back({from, to});
+ };
+ for (int i = 0; i < message->field_count(); i++) {
+ add_ordinal(message->field(i)->number());
+ }
+ for (int i = 0; i < message->extension_count(); i++) {
+ add_ordinal(message->extension(i)->number());
+ }
+ for (int i = 0; i < message->reserved_range_count(); i++) {
+ auto range = message->reserved_range(i);
+ add_range(range->start, range->end);
+ }
+ for (int i = 0; i < message->extension_range_count(); i++) {
+ auto range = message->extension_range(i);
+ add_range(range->start, range->end);
+ }
+ used_ordinals.push_back(
+ {FieldDescriptor::kMaxNumber, FieldDescriptor::kMaxNumber + 1});
+ used_ordinals.push_back({FieldDescriptor::kFirstReservedNumber,
+ FieldDescriptor::kLastReservedNumber});
+ std::sort(used_ordinals.begin(), used_ordinals.end(),
+ [](Range lhs, Range rhs) {
+ return std::tie(lhs.from, lhs.to) < std::tie(rhs.from, rhs.to);
+ });
+ int current_ordinal = 1;
+ std::stringstream id_list;
+ id_list << "Suggested field numbers for " << message->full_name() << ": ";
+ const char* separator = "";
+ for (auto& current_range : used_ordinals) {
+ while (current_ordinal < current_range.from && fields_to_suggest > 0) {
+ id_list << separator << current_ordinal++;
+ separator = ", ";
+ fields_to_suggest--;
+ }
+ if (fields_to_suggest == 0) break;
+ current_ordinal = std::max(current_ordinal, current_range.to);
+ }
+ if (hints->first_reason) {
+ AddError(message->full_name(), *hints->first_reason,
+ hints->first_reason_location, id_list.str());
+ }
+ }
+}
+
+// -------------------------------------------------------------------
+
+#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 std::string ToLowercaseWithoutUnderscores(const std::string& name) {
+ std::string 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<std::string, const FieldDescriptor*> name_to_field;
+ for (int i = 0; i < message->field_count(); ++i) {
+ std::string 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 int64_t max_extension_range =
+ static_cast<int64_t>(message->options().message_set_wire_format()
+ ? std::numeric_limits<int32_t>::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() || field->options().unverified_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, std::string> 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()) {
+ std::string 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 std::string& 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<std::string, 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<std::string, 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.");
+ break;
+ }
+ }
+ // 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<std::string, 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<std::string, 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<std::string, 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);
+
+ std::string 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;
+ std::string 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 std::string& 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: {
+ std::string* outstr =
+ parent_unknown_fields->AddLengthDelimited((*iter)->number());
+ GOOGLE_CHECK(unknown_fields->SerializeToString(outstr))
+ << "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<int64_t>(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 std::string& 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<uint64_t>(std::numeric_limits<int32_t>::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<int64_t>(std::numeric_limits<int32_t>::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<uint64_t>(std::numeric_limits<int64_t>::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<uint32_t>::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:
+ uint64_t 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 std::string& 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.
+ std::string 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 int32_t
+ // to uint64_t, without first going through uint32_t.
+ unknown_fields->AddVarint(
+ option_field->number(),
+ static_cast<uint64_t>(static_cast<int64_t>(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 std::string& prefix,
+ const std::string& 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 std::string& 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:
+ std::string error_;
+
+ void AddError(int /* line */, int /* column */,
+ const std::string& message) override {
+ if (!error_.empty()) {
+ error_ += "; ";
+ }
+ error_ += message;
+ }
+
+ void AddWarning(int /* line */, int /* column */,
+ const std::string& /* 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 {
+ std::string 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, int32_t value, FieldDescriptor::Type type,
+ UnknownFieldSet* unknown_fields) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32:
+ unknown_fields->AddVarint(
+ number, static_cast<uint64_t>(static_cast<int64_t>(value)));
+ break;
+
+ case FieldDescriptor::TYPE_SFIXED32:
+ unknown_fields->AddFixed32(number, static_cast<uint32_t>(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, int64_t value, FieldDescriptor::Type type,
+ UnknownFieldSet* unknown_fields) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT64:
+ unknown_fields->AddVarint(number, static_cast<uint64_t>(value));
+ break;
+
+ case FieldDescriptor::TYPE_SFIXED64:
+ unknown_fields->AddFixed64(number, static_cast<uint64_t>(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, uint32_t value, FieldDescriptor::Type type,
+ UnknownFieldSet* unknown_fields) {
+ switch (type) {
+ case FieldDescriptor::TYPE_UINT32:
+ unknown_fields->AddVarint(number, static_cast<uint64_t>(value));
+ break;
+
+ case FieldDescriptor::TYPE_FIXED32:
+ unknown_fields->AddFixed32(number, static_cast<uint32_t>(value));
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type;
+ break;
+ }
+}
+
+void DescriptorBuilder::OptionInterpreter::SetUInt64(
+ int number, uint64_t 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) {
+ std::string 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 = std::string(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;
+ const char* lazy_type_name = reinterpret_cast<const char*>(type_once_ + 1);
+ const char* lazy_default_value_enum_name =
+ lazy_type_name + strlen(lazy_type_name) + 1;
+ Symbol result = file()->pool()->CrossLinkOnDemandHelper(
+ 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[0] != '\0') {
+ // Have to build the full name now instead of at CrossLink time,
+ // because enum_type may not be known at the time.
+ std::string name = enum_type->full_name();
+ // Enum values reside in the same scope as the enum type.
+ std::string::size_type last_dot = name.find_last_of('.');
+ if (last_dot != std::string::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 std::string& 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);
+ const char* names_ptr = reinterpret_cast<const char*>(dependencies_once_ + 1);
+ for (int i = 0; i < dependency_count(); i++) {
+ const char* name = names_ptr;
+ names_ptr += strlen(name) + 1;
+ if (name[0] != '\0') {
+ dependencies_[i] = pool_->FindFileByName(name);
+ }
+ }
+}
+
+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_,
+ 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_ = ::new (file->pool_->tables_->AllocateBytes(static_cast<int>(
+ sizeof(internal::once_flag) + name.size() + 1))) internal::once_flag{};
+ char* lazy_name = reinterpret_cast<char*>(once_ + 1);
+ memcpy(lazy_name, name.data(), name.size());
+ lazy_name[name.size()] = 0;
+}
+
+void LazyDescriptor::Once(const ServiceDescriptor* service) {
+ if (once_) {
+ internal::call_once(*once_, [&] {
+ auto* file = service->file();
+ GOOGLE_CHECK(file->finished_building_);
+ const char* lazy_name = reinterpret_cast<const char*>(once_ + 1);
+ descriptor_ =
+ file->pool_->CrossLinkOnDemandHelper(lazy_name, false).descriptor();
+ });
+ }
+}
+
+} // namespace internal
+
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
diff --git a/toolkit/components/protobuf/src/google/protobuf/descriptor.h b/toolkit/components/protobuf/src/google/protobuf/descriptor.h
new file mode 100644
index 0000000000..1b8728ec63
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/descriptor.h
@@ -0,0 +1,2440 @@
+// 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>
+
+// Must be included last.
+#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.
+ std::string leading_comments;
+ std::string trailing_comments;
+ std::vector<std::string> 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 {
+
+// The classes in this file represent a significant memory footprint for the
+// library. We make sure we are not accidentally making them larger by
+// hardcoding the struct size for a specific platform. Use as:
+//
+// PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(type, expected_size_in_x84-64);
+//
+
+#if !defined(PROTOBUF_INTERNAL_CHECK_CLASS_SIZE)
+#define PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(t, expected)
+#endif
+
+class FlatAllocator;
+
+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);
+
+ const Descriptor* descriptor_;
+ // The once_ flag is followed by a NUL terminated string for the type 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 std::string& 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 std::string& 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.
+ std::string DebugString() const;
+
+ // Similar to DebugString(), but additionally takes options (e.g.,
+ // include original user comments in output).
+ std::string 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 std::string& 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, std::string* 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 std::string* 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 std::string** 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);
+};
+
+PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(Descriptor, 136);
+
+// 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 std::string& name() const; // Name of this field within the message.
+ const std::string& full_name() const; // Fully-qualified name of the field.
+ const std::string& 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 std::string& 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 std::string& 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.
+ int32_t default_value_int32_t() const;
+ int32_t default_value_int32() const { return default_value_int32_t(); }
+ // Get the field default value if cpp_type() == CPPTYPE_INT64. If no
+ // explicit default was defined, the default is 0.
+ int64_t default_value_int64_t() const;
+ int64_t default_value_int64() const { return default_value_int64_t(); }
+ // Get the field default value if cpp_type() == CPPTYPE_UINT32. If no
+ // explicit default was defined, the default is 0.
+ uint32_t default_value_uint32_t() const;
+ uint32_t default_value_uint32() const { return default_value_uint32_t(); }
+ // Get the field default value if cpp_type() == CPPTYPE_UINT64. If no
+ // explicit default was defined, the default is 0.
+ uint64_t default_value_uint64_t() const;
+ uint64_t default_value_uint64() const { return default_value_uint64_t(); }
+ // 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 std::string& 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().
+ std::string DebugString() const;
+
+ // See Descriptor::DebugStringWithOptions().
+ std::string 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 std::string& 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, std::string* 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.
+ std::string DefaultValueAsString(bool quote_string_type) const;
+
+ // Helper function that returns the field type name for DebugString.
+ std::string 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 std::string* all_names_;
+ const FileDescriptor* file_;
+
+ // The once_flag is followed by a NUL terminated string for the type name and
+ // enum default value (or empty string if no default enum).
+ 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;
+ } 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 {
+ int32_t default_value_int32_t_;
+ int64_t default_value_int64_t_;
+ uint32_t default_value_uint32_t_;
+ uint64_t default_value_uint64_t_;
+ float default_value_float_;
+ double default_value_double_;
+ bool default_value_bool_;
+
+ mutable const EnumValueDescriptor* default_value_enum_;
+ const std::string* 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);
+};
+
+PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(FieldDescriptor, 72);
+
+// Describes a oneof defined in a message type.
+class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase {
+ public:
+ typedef OneofDescriptorProto Proto;
+
+ const std::string& name() const; // Name of this oneof.
+ const std::string& 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().
+ std::string DebugString() const;
+
+ // See Descriptor::DebugStringWithOptions().
+ std::string 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, std::string* 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 std::string* 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);
+};
+
+PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(OneofDescriptor, 40);
+
+// 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 std::string& name() const;
+
+ // The fully-qualified name of the enum type, scope delimited by periods.
+ const std::string& 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().
+ std::string DebugString() const;
+
+ // See Descriptor::DebugStringWithOptions().
+ std::string 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 std::string& 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, std::string* 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 std::string* 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 std::string** 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);
+};
+
+PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumDescriptor, 72);
+
+// 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 std::string& 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 std::string& 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().
+ std::string DebugString() const;
+
+ // See Descriptor::DebugStringWithOptions().
+ std::string 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, std::string* 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 std::string* 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);
+};
+
+PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumValueDescriptor, 32);
+
+// 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 std::string& name() const;
+ // The fully-qualified name of the service, scope delimited by periods.
+ const std::string& 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().
+ std::string DebugString() const;
+
+ // See Descriptor::DebugStringWithOptions().
+ std::string 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(std::string* 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 std::string* 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);
+};
+
+PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(ServiceDescriptor, 48);
+
+// 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 std::string& name() const;
+ // The fully-qualified name of the method, scope delimited by periods.
+ const std::string& 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().
+ std::string DebugString() const;
+
+ // See Descriptor::DebugStringWithOptions().
+ std::string 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, std::string* 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 std::string* 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);
+};
+
+PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(MethodDescriptor, 64);
+
+// 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 : private internal::SymbolBase {
+ public:
+ typedef FileDescriptorProto Proto;
+
+ // The filename, relative to the source tree.
+ // e.g. "foo/bar/baz.proto"
+ const std::string& name() const;
+
+ // The package, e.g. "google.protobuf.compiler".
+ const std::string& 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().
+ std::string DebugString() const;
+
+ // See Descriptor::DebugStringWithOptions().
+ std::string 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:
+ friend class Symbol;
+ typedef FileOptions OptionsType;
+
+ 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_;
+
+ const std::string* name_;
+ const std::string* package_;
+ const DescriptorPool* pool_;
+
+ // dependencies_once_ contain a once_flag followed by N NUL terminated
+ // strings. Dependencies that do not need to be loaded will be empty. ie just
+ // {'\0'}
+ internal::once_flag* 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_;
+
+ 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);
+};
+
+PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(FileDescriptor, 144);
+
+// ===================================================================
+
+// 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 std::string& filename, // File name in which the error occurred.
+ const std::string& 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 std::string& 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 std::string& /*filename*/, // File name in which the error
+ // occurred.
+ const std::string& /*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 std::string& /*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 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, internal::FlatAllocator& alloc) 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<std::string, 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 std::string& 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 std::string& CLASS::name() const { return all_names_[0]; } \
+ inline const std::string& 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_int32_t, int32_t)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64_t, int64_t)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint32_t, uint32_t)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint64_t, uint64_t)
+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 std::string& 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 std::string& EnumDescriptor::reserved_name(int index) const {
+ return *reserved_names_[index];
+}
+
+inline const std::string& FieldDescriptor::lowercase_name() const {
+ return all_names_[lowercase_name_index_];
+}
+
+inline const std::string& FieldDescriptor::camelcase_name() const {
+ return all_names_[camelcase_name_index_];
+}
+
+inline const std::string& 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
+
+#undef PROTOBUF_INTERNAL_CHECK_CLASS_SIZE
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_DESCRIPTOR_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/descriptor.pb.cc b/toolkit/components/protobuf/src/google/protobuf/descriptor.pb.cc
new file mode 100644
index 0000000000..d3bfb461ea
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/descriptor.pb.cc
@@ -0,0 +1,11351 @@
+// 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
+
+namespace _pb = ::PROTOBUF_NAMESPACE_ID;
+namespace _pbi = _pb::internal;
+
+PROTOBUF_NAMESPACE_OPEN
+PROTOBUF_CONSTEXPR FileDescriptorSet::FileDescriptorSet(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.file_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct FileDescriptorSetDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR FileDescriptorSetDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~FileDescriptorSetDefaultTypeInternal() {}
+ union {
+ FileDescriptorSet _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FileDescriptorSetDefaultTypeInternal _FileDescriptorSet_default_instance_;
+PROTOBUF_CONSTEXPR FileDescriptorProto::FileDescriptorProto(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.dependency_)*/{}
+ , /*decltype(_impl_.message_type_)*/{}
+ , /*decltype(_impl_.enum_type_)*/{}
+ , /*decltype(_impl_.service_)*/{}
+ , /*decltype(_impl_.extension_)*/{}
+ , /*decltype(_impl_.public_dependency_)*/{}
+ , /*decltype(_impl_.weak_dependency_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.package_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.syntax_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.options_)*/nullptr
+ , /*decltype(_impl_.source_code_info_)*/nullptr} {}
+struct FileDescriptorProtoDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR FileDescriptorProtoDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~FileDescriptorProtoDefaultTypeInternal() {}
+ union {
+ FileDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FileDescriptorProtoDefaultTypeInternal _FileDescriptorProto_default_instance_;
+PROTOBUF_CONSTEXPR DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.options_)*/nullptr
+ , /*decltype(_impl_.start_)*/0
+ , /*decltype(_impl_.end_)*/0} {}
+struct DescriptorProto_ExtensionRangeDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR DescriptorProto_ExtensionRangeDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~DescriptorProto_ExtensionRangeDefaultTypeInternal() {}
+ union {
+ DescriptorProto_ExtensionRange _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 DescriptorProto_ExtensionRangeDefaultTypeInternal _DescriptorProto_ExtensionRange_default_instance_;
+PROTOBUF_CONSTEXPR DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.start_)*/0
+ , /*decltype(_impl_.end_)*/0} {}
+struct DescriptorProto_ReservedRangeDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR DescriptorProto_ReservedRangeDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~DescriptorProto_ReservedRangeDefaultTypeInternal() {}
+ union {
+ DescriptorProto_ReservedRange _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 DescriptorProto_ReservedRangeDefaultTypeInternal _DescriptorProto_ReservedRange_default_instance_;
+PROTOBUF_CONSTEXPR DescriptorProto::DescriptorProto(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.field_)*/{}
+ , /*decltype(_impl_.nested_type_)*/{}
+ , /*decltype(_impl_.enum_type_)*/{}
+ , /*decltype(_impl_.extension_range_)*/{}
+ , /*decltype(_impl_.extension_)*/{}
+ , /*decltype(_impl_.oneof_decl_)*/{}
+ , /*decltype(_impl_.reserved_range_)*/{}
+ , /*decltype(_impl_.reserved_name_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.options_)*/nullptr} {}
+struct DescriptorProtoDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR DescriptorProtoDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~DescriptorProtoDefaultTypeInternal() {}
+ union {
+ DescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 DescriptorProtoDefaultTypeInternal _DescriptorProto_default_instance_;
+PROTOBUF_CONSTEXPR ExtensionRangeOptions::ExtensionRangeOptions(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , /*decltype(_impl_.uninterpreted_option_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct ExtensionRangeOptionsDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR ExtensionRangeOptionsDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~ExtensionRangeOptionsDefaultTypeInternal() {}
+ union {
+ ExtensionRangeOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ExtensionRangeOptionsDefaultTypeInternal _ExtensionRangeOptions_default_instance_;
+PROTOBUF_CONSTEXPR FieldDescriptorProto::FieldDescriptorProto(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.extendee_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.type_name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.default_value_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.json_name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.options_)*/nullptr
+ , /*decltype(_impl_.number_)*/0
+ , /*decltype(_impl_.oneof_index_)*/0
+ , /*decltype(_impl_.proto3_optional_)*/false
+ , /*decltype(_impl_.label_)*/1
+ , /*decltype(_impl_.type_)*/1} {}
+struct FieldDescriptorProtoDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR FieldDescriptorProtoDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~FieldDescriptorProtoDefaultTypeInternal() {}
+ union {
+ FieldDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FieldDescriptorProtoDefaultTypeInternal _FieldDescriptorProto_default_instance_;
+PROTOBUF_CONSTEXPR OneofDescriptorProto::OneofDescriptorProto(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.options_)*/nullptr} {}
+struct OneofDescriptorProtoDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR OneofDescriptorProtoDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~OneofDescriptorProtoDefaultTypeInternal() {}
+ union {
+ OneofDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 OneofDescriptorProtoDefaultTypeInternal _OneofDescriptorProto_default_instance_;
+PROTOBUF_CONSTEXPR EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.start_)*/0
+ , /*decltype(_impl_.end_)*/0} {}
+struct EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal() {}
+ union {
+ EnumDescriptorProto_EnumReservedRange _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal _EnumDescriptorProto_EnumReservedRange_default_instance_;
+PROTOBUF_CONSTEXPR EnumDescriptorProto::EnumDescriptorProto(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.value_)*/{}
+ , /*decltype(_impl_.reserved_range_)*/{}
+ , /*decltype(_impl_.reserved_name_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.options_)*/nullptr} {}
+struct EnumDescriptorProtoDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR EnumDescriptorProtoDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~EnumDescriptorProtoDefaultTypeInternal() {}
+ union {
+ EnumDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumDescriptorProtoDefaultTypeInternal _EnumDescriptorProto_default_instance_;
+PROTOBUF_CONSTEXPR EnumValueDescriptorProto::EnumValueDescriptorProto(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.options_)*/nullptr
+ , /*decltype(_impl_.number_)*/0} {}
+struct EnumValueDescriptorProtoDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR EnumValueDescriptorProtoDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~EnumValueDescriptorProtoDefaultTypeInternal() {}
+ union {
+ EnumValueDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumValueDescriptorProtoDefaultTypeInternal _EnumValueDescriptorProto_default_instance_;
+PROTOBUF_CONSTEXPR ServiceDescriptorProto::ServiceDescriptorProto(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.method_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.options_)*/nullptr} {}
+struct ServiceDescriptorProtoDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR ServiceDescriptorProtoDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~ServiceDescriptorProtoDefaultTypeInternal() {}
+ union {
+ ServiceDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ServiceDescriptorProtoDefaultTypeInternal _ServiceDescriptorProto_default_instance_;
+PROTOBUF_CONSTEXPR MethodDescriptorProto::MethodDescriptorProto(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.input_type_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.output_type_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.options_)*/nullptr
+ , /*decltype(_impl_.client_streaming_)*/false
+ , /*decltype(_impl_.server_streaming_)*/false} {}
+struct MethodDescriptorProtoDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR MethodDescriptorProtoDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~MethodDescriptorProtoDefaultTypeInternal() {}
+ union {
+ MethodDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MethodDescriptorProtoDefaultTypeInternal _MethodDescriptorProto_default_instance_;
+PROTOBUF_CONSTEXPR FileOptions::FileOptions(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.uninterpreted_option_)*/{}
+ , /*decltype(_impl_.java_package_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.java_outer_classname_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.go_package_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.objc_class_prefix_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.csharp_namespace_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.swift_prefix_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.php_class_prefix_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.php_namespace_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.php_metadata_namespace_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.ruby_package_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.java_multiple_files_)*/false
+ , /*decltype(_impl_.java_generate_equals_and_hash_)*/false
+ , /*decltype(_impl_.java_string_check_utf8_)*/false
+ , /*decltype(_impl_.cc_generic_services_)*/false
+ , /*decltype(_impl_.java_generic_services_)*/false
+ , /*decltype(_impl_.py_generic_services_)*/false
+ , /*decltype(_impl_.php_generic_services_)*/false
+ , /*decltype(_impl_.deprecated_)*/false
+ , /*decltype(_impl_.optimize_for_)*/1
+ , /*decltype(_impl_.cc_enable_arenas_)*/true} {}
+struct FileOptionsDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR FileOptionsDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~FileOptionsDefaultTypeInternal() {}
+ union {
+ FileOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FileOptionsDefaultTypeInternal _FileOptions_default_instance_;
+PROTOBUF_CONSTEXPR MessageOptions::MessageOptions(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.uninterpreted_option_)*/{}
+ , /*decltype(_impl_.message_set_wire_format_)*/false
+ , /*decltype(_impl_.no_standard_descriptor_accessor_)*/false
+ , /*decltype(_impl_.deprecated_)*/false
+ , /*decltype(_impl_.map_entry_)*/false} {}
+struct MessageOptionsDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR MessageOptionsDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~MessageOptionsDefaultTypeInternal() {}
+ union {
+ MessageOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MessageOptionsDefaultTypeInternal _MessageOptions_default_instance_;
+PROTOBUF_CONSTEXPR FieldOptions::FieldOptions(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.uninterpreted_option_)*/{}
+ , /*decltype(_impl_.ctype_)*/0
+ , /*decltype(_impl_.jstype_)*/0
+ , /*decltype(_impl_.packed_)*/false
+ , /*decltype(_impl_.lazy_)*/false
+ , /*decltype(_impl_.unverified_lazy_)*/false
+ , /*decltype(_impl_.deprecated_)*/false
+ , /*decltype(_impl_.weak_)*/false} {}
+struct FieldOptionsDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR FieldOptionsDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~FieldOptionsDefaultTypeInternal() {}
+ union {
+ FieldOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FieldOptionsDefaultTypeInternal _FieldOptions_default_instance_;
+PROTOBUF_CONSTEXPR OneofOptions::OneofOptions(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , /*decltype(_impl_.uninterpreted_option_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct OneofOptionsDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR OneofOptionsDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~OneofOptionsDefaultTypeInternal() {}
+ union {
+ OneofOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 OneofOptionsDefaultTypeInternal _OneofOptions_default_instance_;
+PROTOBUF_CONSTEXPR EnumOptions::EnumOptions(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.uninterpreted_option_)*/{}
+ , /*decltype(_impl_.allow_alias_)*/false
+ , /*decltype(_impl_.deprecated_)*/false} {}
+struct EnumOptionsDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR EnumOptionsDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~EnumOptionsDefaultTypeInternal() {}
+ union {
+ EnumOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumOptionsDefaultTypeInternal _EnumOptions_default_instance_;
+PROTOBUF_CONSTEXPR EnumValueOptions::EnumValueOptions(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.uninterpreted_option_)*/{}
+ , /*decltype(_impl_.deprecated_)*/false} {}
+struct EnumValueOptionsDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR EnumValueOptionsDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~EnumValueOptionsDefaultTypeInternal() {}
+ union {
+ EnumValueOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumValueOptionsDefaultTypeInternal _EnumValueOptions_default_instance_;
+PROTOBUF_CONSTEXPR ServiceOptions::ServiceOptions(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.uninterpreted_option_)*/{}
+ , /*decltype(_impl_.deprecated_)*/false} {}
+struct ServiceOptionsDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR ServiceOptionsDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~ServiceOptionsDefaultTypeInternal() {}
+ union {
+ ServiceOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ServiceOptionsDefaultTypeInternal _ServiceOptions_default_instance_;
+PROTOBUF_CONSTEXPR MethodOptions::MethodOptions(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.uninterpreted_option_)*/{}
+ , /*decltype(_impl_.deprecated_)*/false
+ , /*decltype(_impl_.idempotency_level_)*/0} {}
+struct MethodOptionsDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR MethodOptionsDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~MethodOptionsDefaultTypeInternal() {}
+ union {
+ MethodOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MethodOptionsDefaultTypeInternal _MethodOptions_default_instance_;
+PROTOBUF_CONSTEXPR UninterpretedOption_NamePart::UninterpretedOption_NamePart(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.name_part_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.is_extension_)*/false} {}
+struct UninterpretedOption_NamePartDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR UninterpretedOption_NamePartDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~UninterpretedOption_NamePartDefaultTypeInternal() {}
+ union {
+ UninterpretedOption_NamePart _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 UninterpretedOption_NamePartDefaultTypeInternal _UninterpretedOption_NamePart_default_instance_;
+PROTOBUF_CONSTEXPR UninterpretedOption::UninterpretedOption(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.name_)*/{}
+ , /*decltype(_impl_.identifier_value_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.string_value_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.aggregate_value_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.positive_int_value_)*/uint64_t{0u}
+ , /*decltype(_impl_.negative_int_value_)*/int64_t{0}
+ , /*decltype(_impl_.double_value_)*/0} {}
+struct UninterpretedOptionDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR UninterpretedOptionDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~UninterpretedOptionDefaultTypeInternal() {}
+ union {
+ UninterpretedOption _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 UninterpretedOptionDefaultTypeInternal _UninterpretedOption_default_instance_;
+PROTOBUF_CONSTEXPR SourceCodeInfo_Location::SourceCodeInfo_Location(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.path_)*/{}
+ , /*decltype(_impl_._path_cached_byte_size_)*/{0}
+ , /*decltype(_impl_.span_)*/{}
+ , /*decltype(_impl_._span_cached_byte_size_)*/{0}
+ , /*decltype(_impl_.leading_detached_comments_)*/{}
+ , /*decltype(_impl_.leading_comments_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.trailing_comments_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}} {}
+struct SourceCodeInfo_LocationDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR SourceCodeInfo_LocationDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~SourceCodeInfo_LocationDefaultTypeInternal() {}
+ union {
+ SourceCodeInfo_Location _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 SourceCodeInfo_LocationDefaultTypeInternal _SourceCodeInfo_Location_default_instance_;
+PROTOBUF_CONSTEXPR SourceCodeInfo::SourceCodeInfo(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.location_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct SourceCodeInfoDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR SourceCodeInfoDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~SourceCodeInfoDefaultTypeInternal() {}
+ union {
+ SourceCodeInfo _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 SourceCodeInfoDefaultTypeInternal _SourceCodeInfo_default_instance_;
+PROTOBUF_CONSTEXPR GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_._has_bits_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_.path_)*/{}
+ , /*decltype(_impl_._path_cached_byte_size_)*/{0}
+ , /*decltype(_impl_.source_file_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.begin_)*/0
+ , /*decltype(_impl_.end_)*/0} {}
+struct GeneratedCodeInfo_AnnotationDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR GeneratedCodeInfo_AnnotationDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~GeneratedCodeInfo_AnnotationDefaultTypeInternal() {}
+ union {
+ GeneratedCodeInfo_Annotation _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 GeneratedCodeInfo_AnnotationDefaultTypeInternal _GeneratedCodeInfo_Annotation_default_instance_;
+PROTOBUF_CONSTEXPR GeneratedCodeInfo::GeneratedCodeInfo(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.annotation_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct GeneratedCodeInfoDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR GeneratedCodeInfoDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~GeneratedCodeInfoDefaultTypeInternal() {}
+ union {
+ GeneratedCodeInfo _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 GeneratedCodeInfoDefaultTypeInternal _GeneratedCodeInfo_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[27];
+static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[6];
+static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto = nullptr;
+
+const uint32_t TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ ~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, _impl_.file_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_._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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.package_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.dependency_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.public_dependency_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.weak_dependency_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.message_type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.enum_type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.service_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.extension_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.source_code_info_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.syntax_),
+ 0,
+ 1,
+ ~0u,
+ ~0u,
+ ~0u,
+ ~0u,
+ ~0u,
+ ~0u,
+ ~0u,
+ 3,
+ 4,
+ 2,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, _impl_._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, _impl_.start_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, _impl_.end_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, _impl_.options_),
+ 1,
+ 2,
+ 0,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, _impl_._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, _impl_.start_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, _impl_.end_),
+ 0,
+ 1,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_._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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.field_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.extension_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.nested_type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.enum_type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.extension_range_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.oneof_decl_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.reserved_range_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.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, _impl_._extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, _impl_.uninterpreted_option_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_._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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.number_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.label_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.type_name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.extendee_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.default_value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.oneof_index_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.json_name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.proto3_optional_),
+ 0,
+ 6,
+ 9,
+ 10,
+ 2,
+ 1,
+ 3,
+ 7,
+ 4,
+ 5,
+ 8,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, _impl_._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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, _impl_.options_),
+ 0,
+ 1,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, _impl_._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, _impl_.start_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, _impl_.end_),
+ 0,
+ 1,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _impl_._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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _impl_.value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _impl_.options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _impl_.reserved_range_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _impl_.reserved_name_),
+ 0,
+ ~0u,
+ 1,
+ ~0u,
+ ~0u,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, _impl_._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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, _impl_.number_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, _impl_.options_),
+ 0,
+ 2,
+ 1,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, _impl_._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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, _impl_.method_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, _impl_.options_),
+ 0,
+ ~0u,
+ 1,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _impl_._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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _impl_.input_type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _impl_.output_type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _impl_.options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _impl_.client_streaming_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _impl_.server_streaming_),
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_._has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_._extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.java_package_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.java_outer_classname_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.java_multiple_files_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.java_generate_equals_and_hash_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.java_string_check_utf8_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.optimize_for_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.go_package_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.cc_generic_services_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.java_generic_services_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.py_generic_services_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.php_generic_services_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.cc_enable_arenas_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.objc_class_prefix_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.csharp_namespace_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.swift_prefix_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.php_class_prefix_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.php_namespace_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.php_metadata_namespace_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.ruby_package_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.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, _impl_._has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _impl_._extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _impl_.message_set_wire_format_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _impl_.no_standard_descriptor_accessor_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _impl_.deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _impl_.map_entry_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _impl_.uninterpreted_option_),
+ 0,
+ 1,
+ 2,
+ 3,
+ ~0u,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_._has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_._extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.ctype_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.packed_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.jstype_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.lazy_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.unverified_lazy_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.weak_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.uninterpreted_option_),
+ 0,
+ 2,
+ 1,
+ 3,
+ 4,
+ 5,
+ 6,
+ ~0u,
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofOptions, _impl_._extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofOptions, _impl_.uninterpreted_option_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _impl_._has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _impl_._extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _impl_.allow_alias_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _impl_.deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _impl_.uninterpreted_option_),
+ 0,
+ 1,
+ ~0u,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _impl_._has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _impl_._extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _impl_.deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _impl_.uninterpreted_option_),
+ 0,
+ ~0u,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _impl_._has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _impl_._extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _impl_.deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _impl_.uninterpreted_option_),
+ 0,
+ ~0u,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _impl_._has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _impl_._extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _impl_.deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _impl_.idempotency_level_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _impl_.uninterpreted_option_),
+ 0,
+ 1,
+ ~0u,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, _impl_._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, _impl_.name_part_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, _impl_.is_extension_),
+ 0,
+ 1,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_._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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_.identifier_value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_.positive_int_value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_.negative_int_value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_.double_value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_.string_value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_.aggregate_value_),
+ ~0u,
+ 0,
+ 3,
+ 4,
+ 5,
+ 1,
+ 2,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _impl_._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, _impl_.path_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _impl_.span_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _impl_.leading_comments_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _impl_.trailing_comments_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _impl_.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, _impl_.location_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _impl_._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, _impl_.path_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _impl_.source_file_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _impl_.begin_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _impl_.end_),
+ ~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, _impl_.annotation_),
+};
+static const ::_pbi::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, 276, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FieldOptions)},
+ { 284, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::OneofOptions)},
+ { 291, 300, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumOptions)},
+ { 303, 311, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumValueOptions)},
+ { 313, 321, -1, sizeof(::PROTOBUF_NAMESPACE_ID::ServiceOptions)},
+ { 323, 332, -1, sizeof(::PROTOBUF_NAMESPACE_ID::MethodOptions)},
+ { 335, 343, -1, sizeof(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart)},
+ { 345, 358, -1, sizeof(::PROTOBUF_NAMESPACE_ID::UninterpretedOption)},
+ { 365, 376, -1, sizeof(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location)},
+ { 381, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo)},
+ { 388, 398, -1, sizeof(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation)},
+ { 402, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo)},
+};
+
+static const ::_pb::Message* const file_default_instances[] = {
+ &::PROTOBUF_NAMESPACE_ID::_FileDescriptorSet_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_FileDescriptorProto_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_DescriptorProto_ExtensionRange_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_DescriptorProto_ReservedRange_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_DescriptorProto_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_ExtensionRangeOptions_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_FieldDescriptorProto_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_OneofDescriptorProto_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_EnumDescriptorProto_EnumReservedRange_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_EnumDescriptorProto_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_EnumValueDescriptorProto_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_ServiceDescriptorProto_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_MethodDescriptorProto_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_FileOptions_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_MessageOptions_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_FieldOptions_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_OneofOptions_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_EnumOptions_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_EnumValueOptions_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_ServiceOptions_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_MethodOptions_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_UninterpretedOption_NamePart_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_UninterpretedOption_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_Location_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_Annotation_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_default_instance_._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\"\276\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\036\n\017unverified_lazy\030\017 \001(\010:\005false\022\031\n\nd"
+ "eprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n \001(\010:\005fa"
+ "lse\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goo"
+ "gle.protobuf.UninterpretedOption\"/\n\005CTyp"
+ "e\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_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\014One"
+ "ofOptions\022C\n\024uninterpreted_option\030\347\007 \003(\013"
+ "2$.google.protobuf.UninterpretedOption*\t"
+ "\010\350\007\020\200\200\200\200\002\"\223\001\n\013EnumOptions\022\023\n\013allow_alias"
+ "\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022C\n\024uni"
+ "nterpreted_option\030\347\007 \003(\0132$.google.protob"
+ "uf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\005\020\006\""
+ "}\n\020EnumValueOptions\022\031\n\ndeprecated\030\001 \001(\010:"
+ "\005false\022C\n\024uninterpreted_option\030\347\007 \003(\0132$."
+ "google.protobuf.UninterpretedOption*\t\010\350\007"
+ "\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprecated\030!"
+ " \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003"
+ "(\0132$.google.protobuf.UninterpretedOption"
+ "*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n\ndepreca"
+ "ted\030! \001(\010:\005false\022_\n\021idempotency_level\030\" "
+ "\001(\0162/.google.protobuf.MethodOptions.Idem"
+ "potencyLevel:\023IDEMPOTENCY_UNKNOWN\022C\n\024uni"
+ "nterpreted_option\030\347\007 \003(\0132$.google.protob"
+ "uf.UninterpretedOption\"P\n\020IdempotencyLev"
+ "el\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017NO_SIDE_E"
+ "FFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023"
+ "UninterpretedOption\022;\n\004name\030\002 \003(\0132-.goog"
+ "le.protobuf.UninterpretedOption.NamePart"
+ "\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022positive_i"
+ "nt_value\030\004 \001(\004\022\032\n\022negative_int_value\030\005 \001"
+ "(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string_value"
+ "\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n\010NameP"
+ "art\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002"
+ " \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010location\030\001 \003("
+ "\0132(.google.protobuf.SourceCodeInfo.Locat"
+ "ion\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004sp"
+ "an\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003 \001(\t\022\031"
+ "\n\021trailing_comments\030\004 \001(\t\022!\n\031leading_det"
+ "ached_comments\030\006 \003(\t\"\247\001\n\021GeneratedCodeIn"
+ "fo\022A\n\nannotation\030\001 \003(\0132-.google.protobuf"
+ ".GeneratedCodeInfo.Annotation\032O\n\nAnnotat"
+ "ion\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.go"
+ "ogle.protobufB\020DescriptorProtosH\001Z-googl"
+ "e.golang.org/protobuf/types/descriptorpb"
+ "\370\001\001\242\002\003GPB\252\002\032Google.Protobuf.Reflection"
+ ;
+static ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once;
+const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto = {
+ false, false, 6078, 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 ::_pbi::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_PRIORITY2 static ::_pbi::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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorSet)
+}
+FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ FileDescriptorSet* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.file_){from._impl_.file_}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorSet)
+}
+
+inline void FileDescriptorSet::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.file_){arena}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+FileDescriptorSet::~FileDescriptorSet() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorSet)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void FileDescriptorSet::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.file_.~RepeatedPtrField();
+}
+
+void FileDescriptorSet::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void FileDescriptorSet::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorSet)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.file_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FileDescriptorSet::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.FileDescriptorProto file = 1;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_file_size()); i < n; i++) {
+ const auto& repfield = this->_internal_file(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(1, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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->_impl_.file_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileDescriptorSet::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ FileDescriptorSet::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileDescriptorSet::GetClassData() const { return &_class_data_; }
+
+
+void FileDescriptorSet::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<FileDescriptorSet*>(&to_msg);
+ auto& from = static_cast<const FileDescriptorSet&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorSet)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.file_.MergeFrom(from._impl_.file_);
+ _this->_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(_impl_.file_))
+ return false;
+ return true;
+}
+
+void FileDescriptorSet::InternalSwap(FileDescriptorSet* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ _impl_.file_.InternalSwap(&other->_impl_.file_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FileDescriptorSet::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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->_impl_.options_;
+}
+const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo&
+FileDescriptorProto::_Internal::source_code_info(const FileDescriptorProto* msg) {
+ return *msg->_impl_.source_code_info_;
+}
+FileDescriptorProto::FileDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorProto)
+}
+FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ FileDescriptorProto* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.dependency_){from._impl_.dependency_}
+ , decltype(_impl_.message_type_){from._impl_.message_type_}
+ , decltype(_impl_.enum_type_){from._impl_.enum_type_}
+ , decltype(_impl_.service_){from._impl_.service_}
+ , decltype(_impl_.extension_){from._impl_.extension_}
+ , decltype(_impl_.public_dependency_){from._impl_.public_dependency_}
+ , decltype(_impl_.weak_dependency_){from._impl_.weak_dependency_}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.package_){}
+ , decltype(_impl_.syntax_){}
+ , decltype(_impl_.options_){nullptr}
+ , decltype(_impl_.source_code_info_){nullptr}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.package_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.package_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_package()) {
+ _this->_impl_.package_.Set(from._internal_package(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.syntax_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.syntax_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_syntax()) {
+ _this->_impl_.syntax_.Set(from._internal_syntax(),
+ _this->GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::FileOptions(*from._impl_.options_);
+ }
+ if (from._internal_has_source_code_info()) {
+ _this->_impl_.source_code_info_ = new ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo(*from._impl_.source_code_info_);
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorProto)
+}
+
+inline void FileDescriptorProto::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.dependency_){arena}
+ , decltype(_impl_.message_type_){arena}
+ , decltype(_impl_.enum_type_){arena}
+ , decltype(_impl_.service_){arena}
+ , decltype(_impl_.extension_){arena}
+ , decltype(_impl_.public_dependency_){arena}
+ , decltype(_impl_.weak_dependency_){arena}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.package_){}
+ , decltype(_impl_.syntax_){}
+ , decltype(_impl_.options_){nullptr}
+ , decltype(_impl_.source_code_info_){nullptr}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.package_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.package_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.syntax_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.syntax_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+FileDescriptorProto::~FileDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorProto)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void FileDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.dependency_.~RepeatedPtrField();
+ _impl_.message_type_.~RepeatedPtrField();
+ _impl_.enum_type_.~RepeatedPtrField();
+ _impl_.service_.~RepeatedPtrField();
+ _impl_.extension_.~RepeatedPtrField();
+ _impl_.public_dependency_.~RepeatedField();
+ _impl_.weak_dependency_.~RepeatedField();
+ _impl_.name_.Destroy();
+ _impl_.package_.Destroy();
+ _impl_.syntax_.Destroy();
+ if (this != internal_default_instance()) delete _impl_.options_;
+ if (this != internal_default_instance()) delete _impl_.source_code_info_;
+}
+
+void FileDescriptorProto::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void FileDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.dependency_.Clear();
+ _impl_.message_type_.Clear();
+ _impl_.enum_type_.Clear();
+ _impl_.service_.Clear();
+ _impl_.extension_.Clear();
+ _impl_.public_dependency_.Clear();
+ _impl_.weak_dependency_.Clear();
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x0000001fu) {
+ if (cached_has_bits & 0x00000001u) {
+ _impl_.name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _impl_.package_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _impl_.syntax_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000008u) {
+ GOOGLE_DCHECK(_impl_.options_ != nullptr);
+ _impl_.options_->Clear();
+ }
+ if (cached_has_bits & 0x00000010u) {
+ GOOGLE_DCHECK(_impl_.source_code_info_ != nullptr);
+ _impl_.source_code_info_->Clear();
+ }
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FileDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.name");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.package");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.dependency");
+ #endif // !NDEBUG
+ 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.syntax");
+ #endif // !NDEBUG
+ } 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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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 i = 0,
+ n = static_cast<unsigned>(this->_internal_message_type_size()); i < n; i++) {
+ const auto& repfield = this->_internal_message_type(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(4, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_enum_type_size()); i < n; i++) {
+ const auto& repfield = this->_internal_enum_type(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(5, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_service_size()); i < n; i++) {
+ const auto& repfield = this->_internal_service(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(6, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_extension_size()); i < n; i++) {
+ const auto& repfield = this->_internal_extension(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(7, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // optional .google.protobuf.FileOptions options = 8;
+ if (cached_has_bits & 0x00000008u) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(8, _Internal::options(this),
+ _Internal::options(this).GetCachedSize(), target, stream);
+ }
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ if (cached_has_bits & 0x00000010u) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(9, _Internal::source_code_info(this),
+ _Internal::source_code_info(this).GetCachedSize(), 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 = ::_pbi::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 = ::_pbi::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 = ::_pbi::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;
+
+ uint32_t 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(_impl_.dependency_.size());
+ for (int i = 0, n = _impl_.dependency_.size(); i < n; i++) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ _impl_.dependency_.Get(i));
+ }
+
+ // repeated .google.protobuf.DescriptorProto message_type = 4;
+ total_size += 1UL * this->_internal_message_type_size();
+ for (const auto& msg : this->_impl_.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->_impl_.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->_impl_.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->_impl_.extension_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated int32 public_dependency = 10;
+ {
+ size_t data_size = ::_pbi::WireFormatLite::
+ Int32Size(this->_impl_.public_dependency_);
+ total_size += 1 *
+ ::_pbi::FromIntSize(this->_internal_public_dependency_size());
+ total_size += data_size;
+ }
+
+ // repeated int32 weak_dependency = 11;
+ {
+ size_t data_size = ::_pbi::WireFormatLite::
+ Int32Size(this->_impl_.weak_dependency_);
+ total_size += 1 *
+ ::_pbi::FromIntSize(this->_internal_weak_dependency_size());
+ total_size += data_size;
+ }
+
+ cached_has_bits = _impl_._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(
+ *_impl_.options_);
+ }
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ if (cached_has_bits & 0x00000010u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *_impl_.source_code_info_);
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ FileDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileDescriptorProto::GetClassData() const { return &_class_data_; }
+
+
+void FileDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<FileDescriptorProto*>(&to_msg);
+ auto& from = static_cast<const FileDescriptorProto&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.dependency_.MergeFrom(from._impl_.dependency_);
+ _this->_impl_.message_type_.MergeFrom(from._impl_.message_type_);
+ _this->_impl_.enum_type_.MergeFrom(from._impl_.enum_type_);
+ _this->_impl_.service_.MergeFrom(from._impl_.service_);
+ _this->_impl_.extension_.MergeFrom(from._impl_.extension_);
+ _this->_impl_.public_dependency_.MergeFrom(from._impl_.public_dependency_);
+ _this->_impl_.weak_dependency_.MergeFrom(from._impl_.weak_dependency_);
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x0000001fu) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_internal_set_package(from._internal_package());
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _this->_internal_set_syntax(from._internal_syntax());
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::FileOptions::MergeFrom(
+ from._internal_options());
+ }
+ if (cached_has_bits & 0x00000010u) {
+ _this->_internal_mutable_source_code_info()->::PROTOBUF_NAMESPACE_ID::SourceCodeInfo::MergeFrom(
+ from._internal_source_code_info());
+ }
+ }
+ _this->_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(_impl_.message_type_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.enum_type_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.service_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.extension_))
+ return false;
+ if (_internal_has_options()) {
+ if (!_impl_.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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.dependency_.InternalSwap(&other->_impl_.dependency_);
+ _impl_.message_type_.InternalSwap(&other->_impl_.message_type_);
+ _impl_.enum_type_.InternalSwap(&other->_impl_.enum_type_);
+ _impl_.service_.InternalSwap(&other->_impl_.service_);
+ _impl_.extension_.InternalSwap(&other->_impl_.extension_);
+ _impl_.public_dependency_.InternalSwap(&other->_impl_.public_dependency_);
+ _impl_.weak_dependency_.InternalSwap(&other->_impl_.weak_dependency_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.package_, lhs_arena,
+ &other->_impl_.package_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.syntax_, lhs_arena,
+ &other->_impl_.syntax_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.source_code_info_)
+ + sizeof(FileDescriptorProto::_impl_.source_code_info_)
+ - PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.options_)>(
+ reinterpret_cast<char*>(&_impl_.options_),
+ reinterpret_cast<char*>(&other->_impl_.options_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FileDescriptorProto::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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->_impl_.options_;
+}
+DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ExtensionRange)
+}
+DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ DescriptorProto_ExtensionRange* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.options_){nullptr}
+ , decltype(_impl_.start_){}
+ , decltype(_impl_.end_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ if (from._internal_has_options()) {
+ _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions(*from._impl_.options_);
+ }
+ ::memcpy(&_impl_.start_, &from._impl_.start_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.end_) -
+ reinterpret_cast<char*>(&_impl_.start_)) + sizeof(_impl_.end_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ExtensionRange)
+}
+
+inline void DescriptorProto_ExtensionRange::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.options_){nullptr}
+ , decltype(_impl_.start_){0}
+ , decltype(_impl_.end_){0}
+ };
+}
+
+DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() {
+ // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ExtensionRange)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void DescriptorProto_ExtensionRange::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ if (this != internal_default_instance()) delete _impl_.options_;
+}
+
+void DescriptorProto_ExtensionRange::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void DescriptorProto_ExtensionRange::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ExtensionRange)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000001u) {
+ GOOGLE_DCHECK(_impl_.options_ != nullptr);
+ _impl_.options_->Clear();
+ }
+ if (cached_has_bits & 0x00000006u) {
+ ::memset(&_impl_.start_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.end_) -
+ reinterpret_cast<char*>(&_impl_.start_)) + sizeof(_impl_.end_));
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* DescriptorProto_ExtensionRange::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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);
+ _impl_.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);
+ _impl_.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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ // optional int32 start = 1;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_start(), target);
+ }
+
+ // optional int32 end = 2;
+ if (cached_has_bits & 0x00000004u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_end(), target);
+ }
+
+ // optional .google.protobuf.ExtensionRangeOptions options = 3;
+ if (cached_has_bits & 0x00000001u) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(3, _Internal::options(this),
+ _Internal::options(this).GetCachedSize(), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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(
+ *_impl_.options_);
+ }
+
+ // optional int32 start = 1;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_start());
+ }
+
+ // optional int32 end = 2;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_end());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto_ExtensionRange::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ 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_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<DescriptorProto_ExtensionRange*>(&to_msg);
+ auto& from = static_cast<const DescriptorProto_ExtensionRange&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000007u) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions::MergeFrom(
+ from._internal_options());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_impl_.start_ = from._impl_.start_;
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _this->_impl_.end_ = from._impl_.end_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_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 (!_impl_.options_->IsInitialized()) return false;
+ }
+ return true;
+}
+
+void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_.end_)
+ + sizeof(DescriptorProto_ExtensionRange::_impl_.end_)
+ - PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_.options_)>(
+ reinterpret_cast<char*>(&_impl_.options_),
+ reinterpret_cast<char*>(&other->_impl_.options_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto_ExtensionRange::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ReservedRange)
+}
+DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ DescriptorProto_ReservedRange* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.start_){}
+ , decltype(_impl_.end_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ ::memcpy(&_impl_.start_, &from._impl_.start_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.end_) -
+ reinterpret_cast<char*>(&_impl_.start_)) + sizeof(_impl_.end_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ReservedRange)
+}
+
+inline void DescriptorProto_ReservedRange::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.start_){0}
+ , decltype(_impl_.end_){0}
+ };
+}
+
+DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() {
+ // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ReservedRange)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void DescriptorProto_ReservedRange::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void DescriptorProto_ReservedRange::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void DescriptorProto_ReservedRange::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ReservedRange)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ ::memset(&_impl_.start_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.end_) -
+ reinterpret_cast<char*>(&_impl_.start_)) + sizeof(_impl_.end_));
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* DescriptorProto_ReservedRange::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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);
+ _impl_.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);
+ _impl_.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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ // optional int32 start = 1;
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_start(), target);
+ }
+
+ // optional int32 end = 2;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_end(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ // optional int32 start = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_start());
+ }
+
+ // optional int32 end = 2;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_end());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto_ReservedRange::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ 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_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<DescriptorProto_ReservedRange*>(&to_msg);
+ auto& from = static_cast<const DescriptorProto_ReservedRange&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ReservedRange)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_impl_.start_ = from._impl_.start_;
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_impl_.end_ = from._impl_.end_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_.end_)
+ + sizeof(DescriptorProto_ReservedRange::_impl_.end_)
+ - PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_.start_)>(
+ reinterpret_cast<char*>(&_impl_.start_),
+ reinterpret_cast<char*>(&other->_impl_.start_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto_ReservedRange::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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->_impl_.options_;
+}
+DescriptorProto::DescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto)
+}
+DescriptorProto::DescriptorProto(const DescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ DescriptorProto* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.field_){from._impl_.field_}
+ , decltype(_impl_.nested_type_){from._impl_.nested_type_}
+ , decltype(_impl_.enum_type_){from._impl_.enum_type_}
+ , decltype(_impl_.extension_range_){from._impl_.extension_range_}
+ , decltype(_impl_.extension_){from._impl_.extension_}
+ , decltype(_impl_.oneof_decl_){from._impl_.oneof_decl_}
+ , decltype(_impl_.reserved_range_){from._impl_.reserved_range_}
+ , decltype(_impl_.reserved_name_){from._impl_.reserved_name_}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.options_){nullptr}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::MessageOptions(*from._impl_.options_);
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto)
+}
+
+inline void DescriptorProto::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.field_){arena}
+ , decltype(_impl_.nested_type_){arena}
+ , decltype(_impl_.enum_type_){arena}
+ , decltype(_impl_.extension_range_){arena}
+ , decltype(_impl_.extension_){arena}
+ , decltype(_impl_.oneof_decl_){arena}
+ , decltype(_impl_.reserved_range_){arena}
+ , decltype(_impl_.reserved_name_){arena}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.options_){nullptr}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+DescriptorProto::~DescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void DescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.field_.~RepeatedPtrField();
+ _impl_.nested_type_.~RepeatedPtrField();
+ _impl_.enum_type_.~RepeatedPtrField();
+ _impl_.extension_range_.~RepeatedPtrField();
+ _impl_.extension_.~RepeatedPtrField();
+ _impl_.oneof_decl_.~RepeatedPtrField();
+ _impl_.reserved_range_.~RepeatedPtrField();
+ _impl_.reserved_name_.~RepeatedPtrField();
+ _impl_.name_.Destroy();
+ if (this != internal_default_instance()) delete _impl_.options_;
+}
+
+void DescriptorProto::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void DescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.field_.Clear();
+ _impl_.nested_type_.Clear();
+ _impl_.enum_type_.Clear();
+ _impl_.extension_range_.Clear();
+ _impl_.extension_.Clear();
+ _impl_.oneof_decl_.Clear();
+ _impl_.reserved_range_.Clear();
+ _impl_.reserved_name_.Clear();
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _impl_.name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ GOOGLE_DCHECK(_impl_.options_ != nullptr);
+ _impl_.options_->Clear();
+ }
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* DescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.DescriptorProto.name");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.DescriptorProto.reserved_name");
+ #endif // !NDEBUG
+ 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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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 i = 0,
+ n = static_cast<unsigned>(this->_internal_field_size()); i < n; i++) {
+ const auto& repfield = this->_internal_field(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // repeated .google.protobuf.DescriptorProto nested_type = 3;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_nested_type_size()); i < n; i++) {
+ const auto& repfield = this->_internal_nested_type(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(3, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_enum_type_size()); i < n; i++) {
+ const auto& repfield = this->_internal_enum_type(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(4, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_extension_range_size()); i < n; i++) {
+ const auto& repfield = this->_internal_extension_range(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(5, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_extension_size()); i < n; i++) {
+ const auto& repfield = this->_internal_extension(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(6, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // optional .google.protobuf.MessageOptions options = 7;
+ if (cached_has_bits & 0x00000002u) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(7, _Internal::options(this),
+ _Internal::options(this).GetCachedSize(), target, stream);
+ }
+
+ // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_oneof_decl_size()); i < n; i++) {
+ const auto& repfield = this->_internal_oneof_decl(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(8, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_reserved_range_size()); i < n; i++) {
+ const auto& repfield = this->_internal_reserved_range(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(9, repfield, repfield.GetCachedSize(), 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 = ::_pbi::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;
+
+ uint32_t 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->_impl_.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->_impl_.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->_impl_.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->_impl_.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->_impl_.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->_impl_.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->_impl_.reserved_range_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated string reserved_name = 10;
+ total_size += 1 *
+ ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(_impl_.reserved_name_.size());
+ for (int i = 0, n = _impl_.reserved_name_.size(); i < n; i++) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ _impl_.reserved_name_.Get(i));
+ }
+
+ cached_has_bits = _impl_._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(
+ *_impl_.options_);
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ DescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DescriptorProto::GetClassData() const { return &_class_data_; }
+
+
+void DescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<DescriptorProto*>(&to_msg);
+ auto& from = static_cast<const DescriptorProto&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.field_.MergeFrom(from._impl_.field_);
+ _this->_impl_.nested_type_.MergeFrom(from._impl_.nested_type_);
+ _this->_impl_.enum_type_.MergeFrom(from._impl_.enum_type_);
+ _this->_impl_.extension_range_.MergeFrom(from._impl_.extension_range_);
+ _this->_impl_.extension_.MergeFrom(from._impl_.extension_);
+ _this->_impl_.oneof_decl_.MergeFrom(from._impl_.oneof_decl_);
+ _this->_impl_.reserved_range_.MergeFrom(from._impl_.reserved_range_);
+ _this->_impl_.reserved_name_.MergeFrom(from._impl_.reserved_name_);
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::MessageOptions::MergeFrom(
+ from._internal_options());
+ }
+ }
+ _this->_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(_impl_.field_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.nested_type_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.enum_type_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.extension_range_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.extension_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.oneof_decl_))
+ return false;
+ if (_internal_has_options()) {
+ if (!_impl_.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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.field_.InternalSwap(&other->_impl_.field_);
+ _impl_.nested_type_.InternalSwap(&other->_impl_.nested_type_);
+ _impl_.enum_type_.InternalSwap(&other->_impl_.enum_type_);
+ _impl_.extension_range_.InternalSwap(&other->_impl_.extension_range_);
+ _impl_.extension_.InternalSwap(&other->_impl_.extension_);
+ _impl_.oneof_decl_.InternalSwap(&other->_impl_.oneof_decl_);
+ _impl_.reserved_range_.InternalSwap(&other->_impl_.reserved_range_);
+ _impl_.reserved_name_.InternalSwap(&other->_impl_.reserved_name_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ swap(_impl_.options_, other->_impl_.options_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto::GetMetadata() const {
+ return ::_pbi::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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.ExtensionRangeOptions)
+}
+ExtensionRangeOptions::ExtensionRangeOptions(const ExtensionRangeOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ ExtensionRangeOptions* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.ExtensionRangeOptions)
+}
+
+inline void ExtensionRangeOptions::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
+ , decltype(_impl_.uninterpreted_option_){arena}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+ExtensionRangeOptions::~ExtensionRangeOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.ExtensionRangeOptions)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void ExtensionRangeOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_._extensions_.~ExtensionSet();
+ _impl_.uninterpreted_option_.~RepeatedPtrField();
+}
+
+void ExtensionRangeOptions::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void ExtensionRangeOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.ExtensionRangeOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_._extensions_.Clear();
+ _impl_.uninterpreted_option_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* ExtensionRangeOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ const auto& repfield = this->_internal_uninterpreted_option(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _impl_._extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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 += _impl_._extensions_.ByteSize();
+
+ uint32_t 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->_impl_.uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ExtensionRangeOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ ExtensionRangeOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ExtensionRangeOptions::GetClassData() const { return &_class_data_; }
+
+
+void ExtensionRangeOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<ExtensionRangeOptions*>(&to_msg);
+ auto& from = static_cast<const ExtensionRangeOptions&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ExtensionRangeOptions)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
+ _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ _this->_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 (!_impl_._extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void ExtensionRangeOptions::InternalSwap(ExtensionRangeOptions* other) {
+ using std::swap;
+ _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata ExtensionRangeOptions::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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->_impl_.options_;
+}
+FieldDescriptorProto::FieldDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldDescriptorProto)
+}
+FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ FieldDescriptorProto* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.extendee_){}
+ , decltype(_impl_.type_name_){}
+ , decltype(_impl_.default_value_){}
+ , decltype(_impl_.json_name_){}
+ , decltype(_impl_.options_){nullptr}
+ , decltype(_impl_.number_){}
+ , decltype(_impl_.oneof_index_){}
+ , decltype(_impl_.proto3_optional_){}
+ , decltype(_impl_.label_){}
+ , decltype(_impl_.type_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.extendee_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.extendee_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_extendee()) {
+ _this->_impl_.extendee_.Set(from._internal_extendee(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.type_name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.type_name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_type_name()) {
+ _this->_impl_.type_name_.Set(from._internal_type_name(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.default_value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.default_value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_default_value()) {
+ _this->_impl_.default_value_.Set(from._internal_default_value(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.json_name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.json_name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_json_name()) {
+ _this->_impl_.json_name_.Set(from._internal_json_name(),
+ _this->GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::FieldOptions(*from._impl_.options_);
+ }
+ ::memcpy(&_impl_.number_, &from._impl_.number_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.type_) -
+ reinterpret_cast<char*>(&_impl_.number_)) + sizeof(_impl_.type_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldDescriptorProto)
+}
+
+inline void FieldDescriptorProto::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.extendee_){}
+ , decltype(_impl_.type_name_){}
+ , decltype(_impl_.default_value_){}
+ , decltype(_impl_.json_name_){}
+ , decltype(_impl_.options_){nullptr}
+ , decltype(_impl_.number_){0}
+ , decltype(_impl_.oneof_index_){0}
+ , decltype(_impl_.proto3_optional_){false}
+ , decltype(_impl_.label_){1}
+ , decltype(_impl_.type_){1}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.extendee_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.extendee_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.type_name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.type_name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.default_value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.default_value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.json_name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.json_name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+FieldDescriptorProto::~FieldDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FieldDescriptorProto)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void FieldDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.name_.Destroy();
+ _impl_.extendee_.Destroy();
+ _impl_.type_name_.Destroy();
+ _impl_.default_value_.Destroy();
+ _impl_.json_name_.Destroy();
+ if (this != internal_default_instance()) delete _impl_.options_;
+}
+
+void FieldDescriptorProto::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void FieldDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x0000003fu) {
+ if (cached_has_bits & 0x00000001u) {
+ _impl_.name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _impl_.extendee_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _impl_.type_name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _impl_.default_value_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000010u) {
+ _impl_.json_name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000020u) {
+ GOOGLE_DCHECK(_impl_.options_ != nullptr);
+ _impl_.options_->Clear();
+ }
+ }
+ if (cached_has_bits & 0x000000c0u) {
+ ::memset(&_impl_.number_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.oneof_index_) -
+ reinterpret_cast<char*>(&_impl_.number_)) + sizeof(_impl_.oneof_index_));
+ }
+ if (cached_has_bits & 0x00000700u) {
+ _impl_.proto3_optional_ = false;
+ _impl_.label_ = 1;
+ _impl_.type_ = 1;
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FieldDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.name");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.extendee");
+ #endif // !NDEBUG
+ } 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);
+ _impl_.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)) {
+ uint64_t 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)) {
+ uint64_t 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.type_name");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.default_value");
+ #endif // !NDEBUG
+ } 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);
+ _impl_.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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.json_name");
+ #endif // !NDEBUG
+ } 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);
+ _impl_.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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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 = ::_pbi::WireFormatLite::WriteInt32ToArray(3, this->_internal_number(), target);
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+ if (cached_has_bits & 0x00000200u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteEnumToArray(
+ 4, this->_internal_label(), target);
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+ if (cached_has_bits & 0x00000400u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(8, _Internal::options(this),
+ _Internal::options(this).GetCachedSize(), target, stream);
+ }
+
+ // optional int32 oneof_index = 9;
+ if (cached_has_bits & 0x00000080u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::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 = ::_pbi::WireFormatLite::WriteBoolToArray(17, this->_internal_proto3_optional(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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(
+ *_impl_.options_);
+ }
+
+ // optional int32 number = 3;
+ if (cached_has_bits & 0x00000040u) {
+ total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_number());
+ }
+
+ // optional int32 oneof_index = 9;
+ if (cached_has_bits & 0x00000080u) {
+ total_size += ::_pbi::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 +
+ ::_pbi::WireFormatLite::EnumSize(this->_internal_label());
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+ if (cached_has_bits & 0x00000400u) {
+ total_size += 1 +
+ ::_pbi::WireFormatLite::EnumSize(this->_internal_type());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ FieldDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldDescriptorProto::GetClassData() const { return &_class_data_; }
+
+
+void FieldDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<FieldDescriptorProto*>(&to_msg);
+ auto& from = static_cast<const FieldDescriptorProto&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x000000ffu) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_internal_set_extendee(from._internal_extendee());
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _this->_internal_set_type_name(from._internal_type_name());
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _this->_internal_set_default_value(from._internal_default_value());
+ }
+ if (cached_has_bits & 0x00000010u) {
+ _this->_internal_set_json_name(from._internal_json_name());
+ }
+ if (cached_has_bits & 0x00000020u) {
+ _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::FieldOptions::MergeFrom(
+ from._internal_options());
+ }
+ if (cached_has_bits & 0x00000040u) {
+ _this->_impl_.number_ = from._impl_.number_;
+ }
+ if (cached_has_bits & 0x00000080u) {
+ _this->_impl_.oneof_index_ = from._impl_.oneof_index_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ if (cached_has_bits & 0x00000700u) {
+ if (cached_has_bits & 0x00000100u) {
+ _this->_impl_.proto3_optional_ = from._impl_.proto3_optional_;
+ }
+ if (cached_has_bits & 0x00000200u) {
+ _this->_impl_.label_ = from._impl_.label_;
+ }
+ if (cached_has_bits & 0x00000400u) {
+ _this->_impl_.type_ = from._impl_.type_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_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 (!_impl_.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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.extendee_, lhs_arena,
+ &other->_impl_.extendee_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.type_name_, lhs_arena,
+ &other->_impl_.type_name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.default_value_, lhs_arena,
+ &other->_impl_.default_value_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.json_name_, lhs_arena,
+ &other->_impl_.json_name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_.proto3_optional_)
+ + sizeof(FieldDescriptorProto::_impl_.proto3_optional_)
+ - PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_.options_)>(
+ reinterpret_cast<char*>(&_impl_.options_),
+ reinterpret_cast<char*>(&other->_impl_.options_));
+ swap(_impl_.label_, other->_impl_.label_);
+ swap(_impl_.type_, other->_impl_.type_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FieldDescriptorProto::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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->_impl_.options_;
+}
+OneofDescriptorProto::OneofDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofDescriptorProto)
+}
+OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ OneofDescriptorProto* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.options_){nullptr}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::OneofOptions(*from._impl_.options_);
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofDescriptorProto)
+}
+
+inline void OneofDescriptorProto::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.options_){nullptr}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+OneofDescriptorProto::~OneofDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.OneofDescriptorProto)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void OneofDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.name_.Destroy();
+ if (this != internal_default_instance()) delete _impl_.options_;
+}
+
+void OneofDescriptorProto::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void OneofDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.OneofDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _impl_.name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ GOOGLE_DCHECK(_impl_.options_ != nullptr);
+ _impl_.options_->Clear();
+ }
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* OneofDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.OneofDescriptorProto.name");
+ #endif // !NDEBUG
+ } 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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, _Internal::options(this),
+ _Internal::options(this).GetCachedSize(), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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(
+ *_impl_.options_);
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData OneofDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ OneofDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*OneofDescriptorProto::GetClassData() const { return &_class_data_; }
+
+
+void OneofDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<OneofDescriptorProto*>(&to_msg);
+ auto& from = static_cast<const OneofDescriptorProto&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::OneofOptions::MergeFrom(
+ from._internal_options());
+ }
+ }
+ _this->_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 (!_impl_.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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ swap(_impl_.options_, other->_impl_.options_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata OneofDescriptorProto::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+}
+EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ EnumDescriptorProto_EnumReservedRange* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.start_){}
+ , decltype(_impl_.end_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ ::memcpy(&_impl_.start_, &from._impl_.start_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.end_) -
+ reinterpret_cast<char*>(&_impl_.start_)) + sizeof(_impl_.end_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+}
+
+inline void EnumDescriptorProto_EnumReservedRange::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.start_){0}
+ , decltype(_impl_.end_){0}
+ };
+}
+
+EnumDescriptorProto_EnumReservedRange::~EnumDescriptorProto_EnumReservedRange() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void EnumDescriptorProto_EnumReservedRange::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void EnumDescriptorProto_EnumReservedRange::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void EnumDescriptorProto_EnumReservedRange::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ ::memset(&_impl_.start_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.end_) -
+ reinterpret_cast<char*>(&_impl_.start_)) + sizeof(_impl_.end_));
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* EnumDescriptorProto_EnumReservedRange::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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);
+ _impl_.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);
+ _impl_.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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ // optional int32 start = 1;
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_start(), target);
+ }
+
+ // optional int32 end = 2;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_end(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ // optional int32 start = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_start());
+ }
+
+ // optional int32 end = 2;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_end());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumDescriptorProto_EnumReservedRange::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ 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_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<EnumDescriptorProto_EnumReservedRange*>(&to_msg);
+ auto& from = static_cast<const EnumDescriptorProto_EnumReservedRange&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_impl_.start_ = from._impl_.start_;
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_impl_.end_ = from._impl_.end_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_.end_)
+ + sizeof(EnumDescriptorProto_EnumReservedRange::_impl_.end_)
+ - PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_.start_)>(
+ reinterpret_cast<char*>(&_impl_.start_),
+ reinterpret_cast<char*>(&other->_impl_.start_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata EnumDescriptorProto_EnumReservedRange::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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->_impl_.options_;
+}
+EnumDescriptorProto::EnumDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto)
+}
+EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ EnumDescriptorProto* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.value_){from._impl_.value_}
+ , decltype(_impl_.reserved_range_){from._impl_.reserved_range_}
+ , decltype(_impl_.reserved_name_){from._impl_.reserved_name_}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.options_){nullptr}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::EnumOptions(*from._impl_.options_);
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto)
+}
+
+inline void EnumDescriptorProto::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.value_){arena}
+ , decltype(_impl_.reserved_range_){arena}
+ , decltype(_impl_.reserved_name_){arena}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.options_){nullptr}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+EnumDescriptorProto::~EnumDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void EnumDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.value_.~RepeatedPtrField();
+ _impl_.reserved_range_.~RepeatedPtrField();
+ _impl_.reserved_name_.~RepeatedPtrField();
+ _impl_.name_.Destroy();
+ if (this != internal_default_instance()) delete _impl_.options_;
+}
+
+void EnumDescriptorProto::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void EnumDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.value_.Clear();
+ _impl_.reserved_range_.Clear();
+ _impl_.reserved_name_.Clear();
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _impl_.name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ GOOGLE_DCHECK(_impl_.options_ != nullptr);
+ _impl_.options_->Clear();
+ }
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* EnumDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.EnumDescriptorProto.name");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.EnumDescriptorProto.reserved_name");
+ #endif // !NDEBUG
+ 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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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 i = 0,
+ n = static_cast<unsigned>(this->_internal_value_size()); i < n; i++) {
+ const auto& repfield = this->_internal_value(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // optional .google.protobuf.EnumOptions options = 3;
+ if (cached_has_bits & 0x00000002u) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(3, _Internal::options(this),
+ _Internal::options(this).GetCachedSize(), target, stream);
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_reserved_range_size()); i < n; i++) {
+ const auto& repfield = this->_internal_reserved_range(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(4, repfield, repfield.GetCachedSize(), 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 = ::_pbi::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;
+
+ uint32_t 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->_impl_.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->_impl_.reserved_range_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated string reserved_name = 5;
+ total_size += 1 *
+ ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(_impl_.reserved_name_.size());
+ for (int i = 0, n = _impl_.reserved_name_.size(); i < n; i++) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ _impl_.reserved_name_.Get(i));
+ }
+
+ cached_has_bits = _impl_._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(
+ *_impl_.options_);
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ EnumDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumDescriptorProto::GetClassData() const { return &_class_data_; }
+
+
+void EnumDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<EnumDescriptorProto*>(&to_msg);
+ auto& from = static_cast<const EnumDescriptorProto&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.value_.MergeFrom(from._impl_.value_);
+ _this->_impl_.reserved_range_.MergeFrom(from._impl_.reserved_range_);
+ _this->_impl_.reserved_name_.MergeFrom(from._impl_.reserved_name_);
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::EnumOptions::MergeFrom(
+ from._internal_options());
+ }
+ }
+ _this->_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(_impl_.value_))
+ return false;
+ if (_internal_has_options()) {
+ if (!_impl_.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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.value_.InternalSwap(&other->_impl_.value_);
+ _impl_.reserved_range_.InternalSwap(&other->_impl_.reserved_range_);
+ _impl_.reserved_name_.InternalSwap(&other->_impl_.reserved_name_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ swap(_impl_.options_, other->_impl_.options_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata EnumDescriptorProto::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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->_impl_.options_;
+}
+EnumValueDescriptorProto::EnumValueDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueDescriptorProto)
+}
+EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ EnumValueDescriptorProto* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.options_){nullptr}
+ , decltype(_impl_.number_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::EnumValueOptions(*from._impl_.options_);
+ }
+ _this->_impl_.number_ = from._impl_.number_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueDescriptorProto)
+}
+
+inline void EnumValueDescriptorProto::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.options_){nullptr}
+ , decltype(_impl_.number_){0}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+EnumValueDescriptorProto::~EnumValueDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumValueDescriptorProto)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void EnumValueDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.name_.Destroy();
+ if (this != internal_default_instance()) delete _impl_.options_;
+}
+
+void EnumValueDescriptorProto::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void EnumValueDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _impl_.name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ GOOGLE_DCHECK(_impl_.options_ != nullptr);
+ _impl_.options_->Clear();
+ }
+ }
+ _impl_.number_ = 0;
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* EnumValueDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.EnumValueDescriptorProto.name");
+ #endif // !NDEBUG
+ } 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);
+ _impl_.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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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 = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_number(), target);
+ }
+
+ // optional .google.protobuf.EnumValueOptions options = 3;
+ if (cached_has_bits & 0x00000002u) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(3, _Internal::options(this),
+ _Internal::options(this).GetCachedSize(), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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(
+ *_impl_.options_);
+ }
+
+ // optional int32 number = 2;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_number());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValueDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ EnumValueDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValueDescriptorProto::GetClassData() const { return &_class_data_; }
+
+
+void EnumValueDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<EnumValueDescriptorProto*>(&to_msg);
+ auto& from = static_cast<const EnumValueDescriptorProto&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000007u) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::EnumValueOptions::MergeFrom(
+ from._internal_options());
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _this->_impl_.number_ = from._impl_.number_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_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 (!_impl_.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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_.number_)
+ + sizeof(EnumValueDescriptorProto::_impl_.number_)
+ - PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_.options_)>(
+ reinterpret_cast<char*>(&_impl_.options_),
+ reinterpret_cast<char*>(&other->_impl_.options_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata EnumValueDescriptorProto::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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->_impl_.options_;
+}
+ServiceDescriptorProto::ServiceDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceDescriptorProto)
+}
+ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ ServiceDescriptorProto* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.method_){from._impl_.method_}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.options_){nullptr}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::ServiceOptions(*from._impl_.options_);
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceDescriptorProto)
+}
+
+inline void ServiceDescriptorProto::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.method_){arena}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.options_){nullptr}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+ServiceDescriptorProto::~ServiceDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.ServiceDescriptorProto)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void ServiceDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.method_.~RepeatedPtrField();
+ _impl_.name_.Destroy();
+ if (this != internal_default_instance()) delete _impl_.options_;
+}
+
+void ServiceDescriptorProto::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void ServiceDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.method_.Clear();
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _impl_.name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ GOOGLE_DCHECK(_impl_.options_ != nullptr);
+ _impl_.options_->Clear();
+ }
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* ServiceDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.ServiceDescriptorProto.name");
+ #endif // !NDEBUG
+ } 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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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 i = 0,
+ n = static_cast<unsigned>(this->_internal_method_size()); i < n; i++) {
+ const auto& repfield = this->_internal_method(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // optional .google.protobuf.ServiceOptions options = 3;
+ if (cached_has_bits & 0x00000002u) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(3, _Internal::options(this),
+ _Internal::options(this).GetCachedSize(), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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->_impl_.method_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _impl_._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(
+ *_impl_.options_);
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ServiceDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ ServiceDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ServiceDescriptorProto::GetClassData() const { return &_class_data_; }
+
+
+void ServiceDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<ServiceDescriptorProto*>(&to_msg);
+ auto& from = static_cast<const ServiceDescriptorProto&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.method_.MergeFrom(from._impl_.method_);
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::ServiceOptions::MergeFrom(
+ from._internal_options());
+ }
+ }
+ _this->_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(_impl_.method_))
+ return false;
+ if (_internal_has_options()) {
+ if (!_impl_.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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.method_.InternalSwap(&other->_impl_.method_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ swap(_impl_.options_, other->_impl_.options_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata ServiceDescriptorProto::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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->_impl_.options_;
+}
+MethodDescriptorProto::MethodDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodDescriptorProto)
+}
+MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ MethodDescriptorProto* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.input_type_){}
+ , decltype(_impl_.output_type_){}
+ , decltype(_impl_.options_){nullptr}
+ , decltype(_impl_.client_streaming_){}
+ , decltype(_impl_.server_streaming_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.input_type_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.input_type_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_input_type()) {
+ _this->_impl_.input_type_.Set(from._internal_input_type(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.output_type_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.output_type_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_output_type()) {
+ _this->_impl_.output_type_.Set(from._internal_output_type(),
+ _this->GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::MethodOptions(*from._impl_.options_);
+ }
+ ::memcpy(&_impl_.client_streaming_, &from._impl_.client_streaming_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.server_streaming_) -
+ reinterpret_cast<char*>(&_impl_.client_streaming_)) + sizeof(_impl_.server_streaming_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodDescriptorProto)
+}
+
+inline void MethodDescriptorProto::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.input_type_){}
+ , decltype(_impl_.output_type_){}
+ , decltype(_impl_.options_){nullptr}
+ , decltype(_impl_.client_streaming_){false}
+ , decltype(_impl_.server_streaming_){false}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.input_type_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.input_type_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.output_type_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.output_type_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+MethodDescriptorProto::~MethodDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.MethodDescriptorProto)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void MethodDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.name_.Destroy();
+ _impl_.input_type_.Destroy();
+ _impl_.output_type_.Destroy();
+ if (this != internal_default_instance()) delete _impl_.options_;
+}
+
+void MethodDescriptorProto::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void MethodDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.MethodDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x0000000fu) {
+ if (cached_has_bits & 0x00000001u) {
+ _impl_.name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _impl_.input_type_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _impl_.output_type_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000008u) {
+ GOOGLE_DCHECK(_impl_.options_ != nullptr);
+ _impl_.options_->Clear();
+ }
+ }
+ ::memset(&_impl_.client_streaming_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.server_streaming_) -
+ reinterpret_cast<char*>(&_impl_.client_streaming_)) + sizeof(_impl_.server_streaming_));
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* MethodDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.name");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.input_type");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.output_type");
+ #endif // !NDEBUG
+ } 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);
+ _impl_.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);
+ _impl_.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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(4, _Internal::options(this),
+ _Internal::options(this).GetCachedSize(), target, stream);
+ }
+
+ // optional bool client_streaming = 5 [default = false];
+ if (cached_has_bits & 0x00000010u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::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 = ::_pbi::WireFormatLite::WriteBoolToArray(6, this->_internal_server_streaming(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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(
+ *_impl_.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, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MethodDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ MethodDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MethodDescriptorProto::GetClassData() const { return &_class_data_; }
+
+
+void MethodDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<MethodDescriptorProto*>(&to_msg);
+ auto& from = static_cast<const MethodDescriptorProto&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x0000003fu) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_internal_set_input_type(from._internal_input_type());
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _this->_internal_set_output_type(from._internal_output_type());
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::MethodOptions::MergeFrom(
+ from._internal_options());
+ }
+ if (cached_has_bits & 0x00000010u) {
+ _this->_impl_.client_streaming_ = from._impl_.client_streaming_;
+ }
+ if (cached_has_bits & 0x00000020u) {
+ _this->_impl_.server_streaming_ = from._impl_.server_streaming_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_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 (!_impl_.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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.input_type_, lhs_arena,
+ &other->_impl_.input_type_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.output_type_, lhs_arena,
+ &other->_impl_.output_type_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_.server_streaming_)
+ + sizeof(MethodDescriptorProto::_impl_.server_streaming_)
+ - PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_.options_)>(
+ reinterpret_cast<char*>(&_impl_.options_),
+ reinterpret_cast<char*>(&other->_impl_.options_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata MethodDescriptorProto::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FileOptions)
+}
+FileOptions::FileOptions(const FileOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ FileOptions* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
+ , decltype(_impl_.java_package_){}
+ , decltype(_impl_.java_outer_classname_){}
+ , decltype(_impl_.go_package_){}
+ , decltype(_impl_.objc_class_prefix_){}
+ , decltype(_impl_.csharp_namespace_){}
+ , decltype(_impl_.swift_prefix_){}
+ , decltype(_impl_.php_class_prefix_){}
+ , decltype(_impl_.php_namespace_){}
+ , decltype(_impl_.php_metadata_namespace_){}
+ , decltype(_impl_.ruby_package_){}
+ , decltype(_impl_.java_multiple_files_){}
+ , decltype(_impl_.java_generate_equals_and_hash_){}
+ , decltype(_impl_.java_string_check_utf8_){}
+ , decltype(_impl_.cc_generic_services_){}
+ , decltype(_impl_.java_generic_services_){}
+ , decltype(_impl_.py_generic_services_){}
+ , decltype(_impl_.php_generic_services_){}
+ , decltype(_impl_.deprecated_){}
+ , decltype(_impl_.optimize_for_){}
+ , decltype(_impl_.cc_enable_arenas_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ _impl_.java_package_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.java_package_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_java_package()) {
+ _this->_impl_.java_package_.Set(from._internal_java_package(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.java_outer_classname_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.java_outer_classname_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_java_outer_classname()) {
+ _this->_impl_.java_outer_classname_.Set(from._internal_java_outer_classname(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.go_package_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.go_package_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_go_package()) {
+ _this->_impl_.go_package_.Set(from._internal_go_package(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.objc_class_prefix_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.objc_class_prefix_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_objc_class_prefix()) {
+ _this->_impl_.objc_class_prefix_.Set(from._internal_objc_class_prefix(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.csharp_namespace_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.csharp_namespace_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_csharp_namespace()) {
+ _this->_impl_.csharp_namespace_.Set(from._internal_csharp_namespace(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.swift_prefix_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.swift_prefix_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_swift_prefix()) {
+ _this->_impl_.swift_prefix_.Set(from._internal_swift_prefix(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.php_class_prefix_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.php_class_prefix_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_php_class_prefix()) {
+ _this->_impl_.php_class_prefix_.Set(from._internal_php_class_prefix(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.php_namespace_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.php_namespace_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_php_namespace()) {
+ _this->_impl_.php_namespace_.Set(from._internal_php_namespace(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.php_metadata_namespace_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.php_metadata_namespace_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_php_metadata_namespace()) {
+ _this->_impl_.php_metadata_namespace_.Set(from._internal_php_metadata_namespace(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.ruby_package_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.ruby_package_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_ruby_package()) {
+ _this->_impl_.ruby_package_.Set(from._internal_ruby_package(),
+ _this->GetArenaForAllocation());
+ }
+ ::memcpy(&_impl_.java_multiple_files_, &from._impl_.java_multiple_files_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.cc_enable_arenas_) -
+ reinterpret_cast<char*>(&_impl_.java_multiple_files_)) + sizeof(_impl_.cc_enable_arenas_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FileOptions)
+}
+
+inline void FileOptions::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
+ , decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){arena}
+ , decltype(_impl_.java_package_){}
+ , decltype(_impl_.java_outer_classname_){}
+ , decltype(_impl_.go_package_){}
+ , decltype(_impl_.objc_class_prefix_){}
+ , decltype(_impl_.csharp_namespace_){}
+ , decltype(_impl_.swift_prefix_){}
+ , decltype(_impl_.php_class_prefix_){}
+ , decltype(_impl_.php_namespace_){}
+ , decltype(_impl_.php_metadata_namespace_){}
+ , decltype(_impl_.ruby_package_){}
+ , decltype(_impl_.java_multiple_files_){false}
+ , decltype(_impl_.java_generate_equals_and_hash_){false}
+ , decltype(_impl_.java_string_check_utf8_){false}
+ , decltype(_impl_.cc_generic_services_){false}
+ , decltype(_impl_.java_generic_services_){false}
+ , decltype(_impl_.py_generic_services_){false}
+ , decltype(_impl_.php_generic_services_){false}
+ , decltype(_impl_.deprecated_){false}
+ , decltype(_impl_.optimize_for_){1}
+ , decltype(_impl_.cc_enable_arenas_){true}
+ };
+ _impl_.java_package_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.java_package_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.java_outer_classname_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.java_outer_classname_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.go_package_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.go_package_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.objc_class_prefix_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.objc_class_prefix_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.csharp_namespace_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.csharp_namespace_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.swift_prefix_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.swift_prefix_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.php_class_prefix_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.php_class_prefix_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.php_namespace_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.php_namespace_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.php_metadata_namespace_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.php_metadata_namespace_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.ruby_package_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.ruby_package_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+FileOptions::~FileOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FileOptions)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void FileOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_._extensions_.~ExtensionSet();
+ _impl_.uninterpreted_option_.~RepeatedPtrField();
+ _impl_.java_package_.Destroy();
+ _impl_.java_outer_classname_.Destroy();
+ _impl_.go_package_.Destroy();
+ _impl_.objc_class_prefix_.Destroy();
+ _impl_.csharp_namespace_.Destroy();
+ _impl_.swift_prefix_.Destroy();
+ _impl_.php_class_prefix_.Destroy();
+ _impl_.php_namespace_.Destroy();
+ _impl_.php_metadata_namespace_.Destroy();
+ _impl_.ruby_package_.Destroy();
+}
+
+void FileOptions::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void FileOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FileOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_._extensions_.Clear();
+ _impl_.uninterpreted_option_.Clear();
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x000000ffu) {
+ if (cached_has_bits & 0x00000001u) {
+ _impl_.java_package_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _impl_.java_outer_classname_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _impl_.go_package_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _impl_.objc_class_prefix_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000010u) {
+ _impl_.csharp_namespace_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000020u) {
+ _impl_.swift_prefix_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000040u) {
+ _impl_.php_class_prefix_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000080u) {
+ _impl_.php_namespace_.ClearNonDefaultToEmpty();
+ }
+ }
+ if (cached_has_bits & 0x00000300u) {
+ if (cached_has_bits & 0x00000100u) {
+ _impl_.php_metadata_namespace_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000200u) {
+ _impl_.ruby_package_.ClearNonDefaultToEmpty();
+ }
+ }
+ if (cached_has_bits & 0x0000fc00u) {
+ ::memset(&_impl_.java_multiple_files_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.py_generic_services_) -
+ reinterpret_cast<char*>(&_impl_.java_multiple_files_)) + sizeof(_impl_.py_generic_services_));
+ }
+ if (cached_has_bits & 0x000f0000u) {
+ ::memset(&_impl_.php_generic_services_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.deprecated_) -
+ reinterpret_cast<char*>(&_impl_.php_generic_services_)) + sizeof(_impl_.deprecated_));
+ _impl_.optimize_for_ = 1;
+ _impl_.cc_enable_arenas_ = true;
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FileOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.java_package");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.java_outer_classname");
+ #endif // !NDEBUG
+ } 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)) {
+ uint64_t 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);
+ _impl_.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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.go_package");
+ #endif // !NDEBUG
+ } 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);
+ _impl_.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);
+ _impl_.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);
+ _impl_.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);
+ _impl_.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);
+ _impl_.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);
+ _impl_.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);
+ _impl_.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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.objc_class_prefix");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.csharp_namespace");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.swift_prefix");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.php_class_prefix");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.php_namespace");
+ #endif // !NDEBUG
+ } 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);
+ _impl_.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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.php_metadata_namespace");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.ruby_package");
+ #endif // !NDEBUG
+ } 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 = _impl_._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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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 = ::_pbi::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 = ::_pbi::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 = ::_pbi::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 = ::_pbi::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 = ::_pbi::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 = ::_pbi::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 = ::_pbi::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 = ::_pbi::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 = ::_pbi::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 = ::_pbi::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 i = 0,
+ n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ const auto& repfield = this->_internal_uninterpreted_option(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _impl_._extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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 += _impl_._extensions_.ByteSize();
+
+ uint32_t 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->_impl_.uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _impl_._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 +
+ ::_pbi::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, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ FileOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileOptions::GetClassData() const { return &_class_data_; }
+
+
+void FileOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<FileOptions*>(&to_msg);
+ auto& from = static_cast<const FileOptions&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileOptions)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x000000ffu) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_set_java_package(from._internal_java_package());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_internal_set_java_outer_classname(from._internal_java_outer_classname());
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _this->_internal_set_go_package(from._internal_go_package());
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _this->_internal_set_objc_class_prefix(from._internal_objc_class_prefix());
+ }
+ if (cached_has_bits & 0x00000010u) {
+ _this->_internal_set_csharp_namespace(from._internal_csharp_namespace());
+ }
+ if (cached_has_bits & 0x00000020u) {
+ _this->_internal_set_swift_prefix(from._internal_swift_prefix());
+ }
+ if (cached_has_bits & 0x00000040u) {
+ _this->_internal_set_php_class_prefix(from._internal_php_class_prefix());
+ }
+ if (cached_has_bits & 0x00000080u) {
+ _this->_internal_set_php_namespace(from._internal_php_namespace());
+ }
+ }
+ if (cached_has_bits & 0x0000ff00u) {
+ if (cached_has_bits & 0x00000100u) {
+ _this->_internal_set_php_metadata_namespace(from._internal_php_metadata_namespace());
+ }
+ if (cached_has_bits & 0x00000200u) {
+ _this->_internal_set_ruby_package(from._internal_ruby_package());
+ }
+ if (cached_has_bits & 0x00000400u) {
+ _this->_impl_.java_multiple_files_ = from._impl_.java_multiple_files_;
+ }
+ if (cached_has_bits & 0x00000800u) {
+ _this->_impl_.java_generate_equals_and_hash_ = from._impl_.java_generate_equals_and_hash_;
+ }
+ if (cached_has_bits & 0x00001000u) {
+ _this->_impl_.java_string_check_utf8_ = from._impl_.java_string_check_utf8_;
+ }
+ if (cached_has_bits & 0x00002000u) {
+ _this->_impl_.cc_generic_services_ = from._impl_.cc_generic_services_;
+ }
+ if (cached_has_bits & 0x00004000u) {
+ _this->_impl_.java_generic_services_ = from._impl_.java_generic_services_;
+ }
+ if (cached_has_bits & 0x00008000u) {
+ _this->_impl_.py_generic_services_ = from._impl_.py_generic_services_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ if (cached_has_bits & 0x000f0000u) {
+ if (cached_has_bits & 0x00010000u) {
+ _this->_impl_.php_generic_services_ = from._impl_.php_generic_services_;
+ }
+ if (cached_has_bits & 0x00020000u) {
+ _this->_impl_.deprecated_ = from._impl_.deprecated_;
+ }
+ if (cached_has_bits & 0x00040000u) {
+ _this->_impl_.optimize_for_ = from._impl_.optimize_for_;
+ }
+ if (cached_has_bits & 0x00080000u) {
+ _this->_impl_.cc_enable_arenas_ = from._impl_.cc_enable_arenas_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ _this->_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 (!_impl_._extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void FileOptions::InternalSwap(FileOptions* other) {
+ using std::swap;
+ _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.java_package_, lhs_arena,
+ &other->_impl_.java_package_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.java_outer_classname_, lhs_arena,
+ &other->_impl_.java_outer_classname_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.go_package_, lhs_arena,
+ &other->_impl_.go_package_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.objc_class_prefix_, lhs_arena,
+ &other->_impl_.objc_class_prefix_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.csharp_namespace_, lhs_arena,
+ &other->_impl_.csharp_namespace_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.swift_prefix_, lhs_arena,
+ &other->_impl_.swift_prefix_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.php_class_prefix_, lhs_arena,
+ &other->_impl_.php_class_prefix_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.php_namespace_, lhs_arena,
+ &other->_impl_.php_namespace_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.php_metadata_namespace_, lhs_arena,
+ &other->_impl_.php_metadata_namespace_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.ruby_package_, lhs_arena,
+ &other->_impl_.ruby_package_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(FileOptions, _impl_.deprecated_)
+ + sizeof(FileOptions::_impl_.deprecated_)
+ - PROTOBUF_FIELD_OFFSET(FileOptions, _impl_.java_multiple_files_)>(
+ reinterpret_cast<char*>(&_impl_.java_multiple_files_),
+ reinterpret_cast<char*>(&other->_impl_.java_multiple_files_));
+ swap(_impl_.optimize_for_, other->_impl_.optimize_for_);
+ swap(_impl_.cc_enable_arenas_, other->_impl_.cc_enable_arenas_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FileOptions::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.MessageOptions)
+}
+MessageOptions::MessageOptions(const MessageOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ MessageOptions* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
+ , decltype(_impl_.message_set_wire_format_){}
+ , decltype(_impl_.no_standard_descriptor_accessor_){}
+ , decltype(_impl_.deprecated_){}
+ , decltype(_impl_.map_entry_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ ::memcpy(&_impl_.message_set_wire_format_, &from._impl_.message_set_wire_format_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.map_entry_) -
+ reinterpret_cast<char*>(&_impl_.message_set_wire_format_)) + sizeof(_impl_.map_entry_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.MessageOptions)
+}
+
+inline void MessageOptions::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
+ , decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){arena}
+ , decltype(_impl_.message_set_wire_format_){false}
+ , decltype(_impl_.no_standard_descriptor_accessor_){false}
+ , decltype(_impl_.deprecated_){false}
+ , decltype(_impl_.map_entry_){false}
+ };
+}
+
+MessageOptions::~MessageOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.MessageOptions)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void MessageOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_._extensions_.~ExtensionSet();
+ _impl_.uninterpreted_option_.~RepeatedPtrField();
+}
+
+void MessageOptions::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void MessageOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.MessageOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_._extensions_.Clear();
+ _impl_.uninterpreted_option_.Clear();
+ ::memset(&_impl_.message_set_wire_format_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.map_entry_) -
+ reinterpret_cast<char*>(&_impl_.message_set_wire_format_)) + sizeof(_impl_.map_entry_));
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* MessageOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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);
+ _impl_.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);
+ _impl_.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);
+ _impl_.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);
+ _impl_.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 = _impl_._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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ // optional bool message_set_wire_format = 1 [default = false];
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::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 = ::_pbi::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 = ::_pbi::WireFormatLite::WriteBoolToArray(3, this->_internal_deprecated(), target);
+ }
+
+ // optional bool map_entry = 7;
+ if (cached_has_bits & 0x00000008u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(7, this->_internal_map_entry(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ const auto& repfield = this->_internal_uninterpreted_option(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _impl_._extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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 += _impl_._extensions_.ByteSize();
+
+ uint32_t 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->_impl_.uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _impl_._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, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MessageOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ MessageOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MessageOptions::GetClassData() const { return &_class_data_; }
+
+
+void MessageOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<MessageOptions*>(&to_msg);
+ auto& from = static_cast<const MessageOptions&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MessageOptions)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x0000000fu) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_impl_.message_set_wire_format_ = from._impl_.message_set_wire_format_;
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_impl_.no_standard_descriptor_accessor_ = from._impl_.no_standard_descriptor_accessor_;
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _this->_impl_.deprecated_ = from._impl_.deprecated_;
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _this->_impl_.map_entry_ = from._impl_.map_entry_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ _this->_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 (!_impl_._extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void MessageOptions::InternalSwap(MessageOptions* other) {
+ using std::swap;
+ _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_.map_entry_)
+ + sizeof(MessageOptions::_impl_.map_entry_)
+ - PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_.message_set_wire_format_)>(
+ reinterpret_cast<char*>(&_impl_.message_set_wire_format_),
+ reinterpret_cast<char*>(&other->_impl_.message_set_wire_format_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata MessageOptions::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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] |= 4u;
+ }
+ static void set_has_jstype(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+ static void set_has_lazy(HasBits* has_bits) {
+ (*has_bits)[0] |= 8u;
+ }
+ static void set_has_unverified_lazy(HasBits* has_bits) {
+ (*has_bits)[0] |= 16u;
+ }
+ static void set_has_deprecated(HasBits* has_bits) {
+ (*has_bits)[0] |= 32u;
+ }
+ static void set_has_weak(HasBits* has_bits) {
+ (*has_bits)[0] |= 64u;
+ }
+};
+
+FieldOptions::FieldOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldOptions)
+}
+FieldOptions::FieldOptions(const FieldOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ FieldOptions* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
+ , decltype(_impl_.ctype_){}
+ , decltype(_impl_.jstype_){}
+ , decltype(_impl_.packed_){}
+ , decltype(_impl_.lazy_){}
+ , decltype(_impl_.unverified_lazy_){}
+ , decltype(_impl_.deprecated_){}
+ , decltype(_impl_.weak_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ ::memcpy(&_impl_.ctype_, &from._impl_.ctype_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.weak_) -
+ reinterpret_cast<char*>(&_impl_.ctype_)) + sizeof(_impl_.weak_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldOptions)
+}
+
+inline void FieldOptions::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
+ , decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){arena}
+ , decltype(_impl_.ctype_){0}
+ , decltype(_impl_.jstype_){0}
+ , decltype(_impl_.packed_){false}
+ , decltype(_impl_.lazy_){false}
+ , decltype(_impl_.unverified_lazy_){false}
+ , decltype(_impl_.deprecated_){false}
+ , decltype(_impl_.weak_){false}
+ };
+}
+
+FieldOptions::~FieldOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FieldOptions)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void FieldOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_._extensions_.~ExtensionSet();
+ _impl_.uninterpreted_option_.~RepeatedPtrField();
+}
+
+void FieldOptions::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void FieldOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_._extensions_.Clear();
+ _impl_.uninterpreted_option_.Clear();
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x0000007fu) {
+ ::memset(&_impl_.ctype_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.weak_) -
+ reinterpret_cast<char*>(&_impl_.ctype_)) + sizeof(_impl_.weak_));
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FieldOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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)) {
+ uint64_t 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);
+ _impl_.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);
+ _impl_.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);
+ _impl_.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)) {
+ uint64_t 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);
+ _impl_.weak_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool unverified_lazy = 15 [default = false];
+ case 15:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 120)) {
+ _Internal::set_has_unverified_lazy(&has_bits);
+ _impl_.unverified_lazy_ = ::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 = _impl_._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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteEnumToArray(
+ 1, this->_internal_ctype(), target);
+ }
+
+ // optional bool packed = 2;
+ if (cached_has_bits & 0x00000004u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(2, this->_internal_packed(), target);
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (cached_has_bits & 0x00000020u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(3, this->_internal_deprecated(), target);
+ }
+
+ // optional bool lazy = 5 [default = false];
+ if (cached_has_bits & 0x00000008u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(5, this->_internal_lazy(), target);
+ }
+
+ // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteEnumToArray(
+ 6, this->_internal_jstype(), target);
+ }
+
+ // optional bool weak = 10 [default = false];
+ if (cached_has_bits & 0x00000040u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(10, this->_internal_weak(), target);
+ }
+
+ // optional bool unverified_lazy = 15 [default = false];
+ if (cached_has_bits & 0x00000010u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(15, this->_internal_unverified_lazy(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ const auto& repfield = this->_internal_uninterpreted_option(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _impl_._extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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 += _impl_._extensions_.ByteSize();
+
+ uint32_t 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->_impl_.uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x0000007fu) {
+ // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::_pbi::WireFormatLite::EnumSize(this->_internal_ctype());
+ }
+
+ // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::_pbi::WireFormatLite::EnumSize(this->_internal_jstype());
+ }
+
+ // optional bool packed = 2;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool lazy = 5 [default = false];
+ if (cached_has_bits & 0x00000008u) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool unverified_lazy = 15 [default = false];
+ if (cached_has_bits & 0x00000010u) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (cached_has_bits & 0x00000020u) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool weak = 10 [default = false];
+ if (cached_has_bits & 0x00000040u) {
+ total_size += 1 + 1;
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ FieldOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldOptions::GetClassData() const { return &_class_data_; }
+
+
+void FieldOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<FieldOptions*>(&to_msg);
+ auto& from = static_cast<const FieldOptions&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldOptions)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x0000007fu) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_impl_.ctype_ = from._impl_.ctype_;
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_impl_.jstype_ = from._impl_.jstype_;
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _this->_impl_.packed_ = from._impl_.packed_;
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _this->_impl_.lazy_ = from._impl_.lazy_;
+ }
+ if (cached_has_bits & 0x00000010u) {
+ _this->_impl_.unverified_lazy_ = from._impl_.unverified_lazy_;
+ }
+ if (cached_has_bits & 0x00000020u) {
+ _this->_impl_.deprecated_ = from._impl_.deprecated_;
+ }
+ if (cached_has_bits & 0x00000040u) {
+ _this->_impl_.weak_ = from._impl_.weak_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ _this->_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 (!_impl_._extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void FieldOptions::InternalSwap(FieldOptions* other) {
+ using std::swap;
+ _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.weak_)
+ + sizeof(FieldOptions::_impl_.weak_)
+ - PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.ctype_)>(
+ reinterpret_cast<char*>(&_impl_.ctype_),
+ reinterpret_cast<char*>(&other->_impl_.ctype_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FieldOptions::GetMetadata() const {
+ return ::_pbi::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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofOptions)
+}
+OneofOptions::OneofOptions(const OneofOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ OneofOptions* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofOptions)
+}
+
+inline void OneofOptions::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
+ , decltype(_impl_.uninterpreted_option_){arena}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+OneofOptions::~OneofOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.OneofOptions)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void OneofOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_._extensions_.~ExtensionSet();
+ _impl_.uninterpreted_option_.~RepeatedPtrField();
+}
+
+void OneofOptions::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void OneofOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.OneofOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_._extensions_.Clear();
+ _impl_.uninterpreted_option_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* OneofOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ const auto& repfield = this->_internal_uninterpreted_option(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _impl_._extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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 += _impl_._extensions_.ByteSize();
+
+ uint32_t 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->_impl_.uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData OneofOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ OneofOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*OneofOptions::GetClassData() const { return &_class_data_; }
+
+
+void OneofOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<OneofOptions*>(&to_msg);
+ auto& from = static_cast<const OneofOptions&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofOptions)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
+ _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ _this->_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 (!_impl_._extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void OneofOptions::InternalSwap(OneofOptions* other) {
+ using std::swap;
+ _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata OneofOptions::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumOptions)
+}
+EnumOptions::EnumOptions(const EnumOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ EnumOptions* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
+ , decltype(_impl_.allow_alias_){}
+ , decltype(_impl_.deprecated_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ ::memcpy(&_impl_.allow_alias_, &from._impl_.allow_alias_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.deprecated_) -
+ reinterpret_cast<char*>(&_impl_.allow_alias_)) + sizeof(_impl_.deprecated_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumOptions)
+}
+
+inline void EnumOptions::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
+ , decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){arena}
+ , decltype(_impl_.allow_alias_){false}
+ , decltype(_impl_.deprecated_){false}
+ };
+}
+
+EnumOptions::~EnumOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumOptions)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void EnumOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_._extensions_.~ExtensionSet();
+ _impl_.uninterpreted_option_.~RepeatedPtrField();
+}
+
+void EnumOptions::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void EnumOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_._extensions_.Clear();
+ _impl_.uninterpreted_option_.Clear();
+ ::memset(&_impl_.allow_alias_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.deprecated_) -
+ reinterpret_cast<char*>(&_impl_.allow_alias_)) + sizeof(_impl_.deprecated_));
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* EnumOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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);
+ _impl_.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);
+ _impl_.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 = _impl_._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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ // optional bool allow_alias = 2;
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(2, this->_internal_allow_alias(), target);
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(3, this->_internal_deprecated(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ const auto& repfield = this->_internal_uninterpreted_option(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _impl_._extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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 += _impl_._extensions_.ByteSize();
+
+ uint32_t 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->_impl_.uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _impl_._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, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ EnumOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumOptions::GetClassData() const { return &_class_data_; }
+
+
+void EnumOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<EnumOptions*>(&to_msg);
+ auto& from = static_cast<const EnumOptions&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumOptions)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_impl_.allow_alias_ = from._impl_.allow_alias_;
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_impl_.deprecated_ = from._impl_.deprecated_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ _this->_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 (!_impl_._extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void EnumOptions::InternalSwap(EnumOptions* other) {
+ using std::swap;
+ _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_.deprecated_)
+ + sizeof(EnumOptions::_impl_.deprecated_)
+ - PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_.allow_alias_)>(
+ reinterpret_cast<char*>(&_impl_.allow_alias_),
+ reinterpret_cast<char*>(&other->_impl_.allow_alias_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata EnumOptions::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueOptions)
+}
+EnumValueOptions::EnumValueOptions(const EnumValueOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ EnumValueOptions* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
+ , decltype(_impl_.deprecated_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ _this->_impl_.deprecated_ = from._impl_.deprecated_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueOptions)
+}
+
+inline void EnumValueOptions::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
+ , decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){arena}
+ , decltype(_impl_.deprecated_){false}
+ };
+}
+
+EnumValueOptions::~EnumValueOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumValueOptions)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void EnumValueOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_._extensions_.~ExtensionSet();
+ _impl_.uninterpreted_option_.~RepeatedPtrField();
+}
+
+void EnumValueOptions::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void EnumValueOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_._extensions_.Clear();
+ _impl_.uninterpreted_option_.Clear();
+ _impl_.deprecated_ = false;
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* EnumValueOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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);
+ _impl_.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 = _impl_._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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ // optional bool deprecated = 1 [default = false];
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(1, this->_internal_deprecated(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ const auto& repfield = this->_internal_uninterpreted_option(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _impl_._extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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 += _impl_._extensions_.ByteSize();
+
+ uint32_t 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->_impl_.uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // optional bool deprecated = 1 [default = false];
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 + 1;
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValueOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ EnumValueOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValueOptions::GetClassData() const { return &_class_data_; }
+
+
+void EnumValueOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<EnumValueOptions*>(&to_msg);
+ auto& from = static_cast<const EnumValueOptions&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueOptions)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
+ if (from._internal_has_deprecated()) {
+ _this->_internal_set_deprecated(from._internal_deprecated());
+ }
+ _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ _this->_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 (!_impl_._extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void EnumValueOptions::InternalSwap(EnumValueOptions* other) {
+ using std::swap;
+ _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
+ swap(_impl_.deprecated_, other->_impl_.deprecated_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata EnumValueOptions::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceOptions)
+}
+ServiceOptions::ServiceOptions(const ServiceOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ ServiceOptions* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
+ , decltype(_impl_.deprecated_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ _this->_impl_.deprecated_ = from._impl_.deprecated_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceOptions)
+}
+
+inline void ServiceOptions::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
+ , decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){arena}
+ , decltype(_impl_.deprecated_){false}
+ };
+}
+
+ServiceOptions::~ServiceOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.ServiceOptions)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void ServiceOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_._extensions_.~ExtensionSet();
+ _impl_.uninterpreted_option_.~RepeatedPtrField();
+}
+
+void ServiceOptions::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void ServiceOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_._extensions_.Clear();
+ _impl_.uninterpreted_option_.Clear();
+ _impl_.deprecated_ = false;
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* ServiceOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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);
+ _impl_.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 = _impl_._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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ // optional bool deprecated = 33 [default = false];
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(33, this->_internal_deprecated(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ const auto& repfield = this->_internal_uninterpreted_option(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _impl_._extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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 += _impl_._extensions_.ByteSize();
+
+ uint32_t 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->_impl_.uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // optional bool deprecated = 33 [default = false];
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 2 + 1;
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ServiceOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ ServiceOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ServiceOptions::GetClassData() const { return &_class_data_; }
+
+
+void ServiceOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<ServiceOptions*>(&to_msg);
+ auto& from = static_cast<const ServiceOptions&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceOptions)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
+ if (from._internal_has_deprecated()) {
+ _this->_internal_set_deprecated(from._internal_deprecated());
+ }
+ _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ _this->_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 (!_impl_._extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void ServiceOptions::InternalSwap(ServiceOptions* other) {
+ using std::swap;
+ _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
+ swap(_impl_.deprecated_, other->_impl_.deprecated_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata ServiceOptions::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodOptions)
+}
+MethodOptions::MethodOptions(const MethodOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ MethodOptions* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{}
+ , decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
+ , decltype(_impl_.deprecated_){}
+ , decltype(_impl_.idempotency_level_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ ::memcpy(&_impl_.deprecated_, &from._impl_.deprecated_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.idempotency_level_) -
+ reinterpret_cast<char*>(&_impl_.deprecated_)) + sizeof(_impl_.idempotency_level_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodOptions)
+}
+
+inline void MethodOptions::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
+ , decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.uninterpreted_option_){arena}
+ , decltype(_impl_.deprecated_){false}
+ , decltype(_impl_.idempotency_level_){0}
+ };
+}
+
+MethodOptions::~MethodOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.MethodOptions)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void MethodOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_._extensions_.~ExtensionSet();
+ _impl_.uninterpreted_option_.~RepeatedPtrField();
+}
+
+void MethodOptions::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void MethodOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.MethodOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_._extensions_.Clear();
+ _impl_.uninterpreted_option_.Clear();
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ ::memset(&_impl_.deprecated_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.idempotency_level_) -
+ reinterpret_cast<char*>(&_impl_.deprecated_)) + sizeof(_impl_.idempotency_level_));
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* MethodOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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);
+ _impl_.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)) {
+ uint64_t 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 = _impl_._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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ // optional bool deprecated = 33 [default = false];
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::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 = ::_pbi::WireFormatLite::WriteEnumToArray(
+ 34, this->_internal_idempotency_level(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ const auto& repfield = this->_internal_uninterpreted_option(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _impl_._extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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 += _impl_._extensions_.ByteSize();
+
+ uint32_t 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->_impl_.uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _impl_._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 +
+ ::_pbi::WireFormatLite::EnumSize(this->_internal_idempotency_level());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MethodOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ MethodOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MethodOptions::GetClassData() const { return &_class_data_; }
+
+
+void MethodOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<MethodOptions*>(&to_msg);
+ auto& from = static_cast<const MethodOptions&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodOptions)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_impl_.deprecated_ = from._impl_.deprecated_;
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_impl_.idempotency_level_ = from._impl_.idempotency_level_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
+ _this->_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 (!_impl_._extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void MethodOptions::InternalSwap(MethodOptions* other) {
+ using std::swap;
+ _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.idempotency_level_)
+ + sizeof(MethodOptions::_impl_.idempotency_level_)
+ - PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.deprecated_)>(
+ reinterpret_cast<char*>(&_impl_.deprecated_),
+ reinterpret_cast<char*>(&other->_impl_.deprecated_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata MethodOptions::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption.NamePart)
+}
+UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ UninterpretedOption_NamePart* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.name_part_){}
+ , decltype(_impl_.is_extension_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_part_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_part_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name_part()) {
+ _this->_impl_.name_part_.Set(from._internal_name_part(),
+ _this->GetArenaForAllocation());
+ }
+ _this->_impl_.is_extension_ = from._impl_.is_extension_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption.NamePart)
+}
+
+inline void UninterpretedOption_NamePart::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.name_part_){}
+ , decltype(_impl_.is_extension_){false}
+ };
+ _impl_.name_part_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_part_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+UninterpretedOption_NamePart::~UninterpretedOption_NamePart() {
+ // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption.NamePart)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void UninterpretedOption_NamePart::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.name_part_.Destroy();
+}
+
+void UninterpretedOption_NamePart::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void UninterpretedOption_NamePart::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption.NamePart)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000001u) {
+ _impl_.name_part_.ClearNonDefaultToEmpty();
+ }
+ _impl_.is_extension_ = false;
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* UninterpretedOption_NamePart::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.UninterpretedOption.NamePart.name_part");
+ #endif // !NDEBUG
+ } 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);
+ _impl_.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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _impl_._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 = ::_pbi::WireFormatLite::WriteBoolToArray(2, this->_internal_is_extension(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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 (((_impl_._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();
+ }
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UninterpretedOption_NamePart::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ 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_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<UninterpretedOption_NamePart*>(&to_msg);
+ auto& from = static_cast<const UninterpretedOption_NamePart&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption.NamePart)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_set_name_part(from._internal_name_part());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_impl_.is_extension_ = from._impl_.is_extension_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_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(_impl_._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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_part_, lhs_arena,
+ &other->_impl_.name_part_, rhs_arena
+ );
+ swap(_impl_.is_extension_, other->_impl_.is_extension_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata UninterpretedOption_NamePart::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption)
+}
+UninterpretedOption::UninterpretedOption(const UninterpretedOption& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ UninterpretedOption* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.name_){from._impl_.name_}
+ , decltype(_impl_.identifier_value_){}
+ , decltype(_impl_.string_value_){}
+ , decltype(_impl_.aggregate_value_){}
+ , decltype(_impl_.positive_int_value_){}
+ , decltype(_impl_.negative_int_value_){}
+ , decltype(_impl_.double_value_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.identifier_value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.identifier_value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_identifier_value()) {
+ _this->_impl_.identifier_value_.Set(from._internal_identifier_value(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.string_value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.string_value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_string_value()) {
+ _this->_impl_.string_value_.Set(from._internal_string_value(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.aggregate_value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.aggregate_value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_aggregate_value()) {
+ _this->_impl_.aggregate_value_.Set(from._internal_aggregate_value(),
+ _this->GetArenaForAllocation());
+ }
+ ::memcpy(&_impl_.positive_int_value_, &from._impl_.positive_int_value_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.double_value_) -
+ reinterpret_cast<char*>(&_impl_.positive_int_value_)) + sizeof(_impl_.double_value_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption)
+}
+
+inline void UninterpretedOption::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.name_){arena}
+ , decltype(_impl_.identifier_value_){}
+ , decltype(_impl_.string_value_){}
+ , decltype(_impl_.aggregate_value_){}
+ , decltype(_impl_.positive_int_value_){uint64_t{0u}}
+ , decltype(_impl_.negative_int_value_){int64_t{0}}
+ , decltype(_impl_.double_value_){0}
+ };
+ _impl_.identifier_value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.identifier_value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.string_value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.string_value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.aggregate_value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.aggregate_value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+UninterpretedOption::~UninterpretedOption() {
+ // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void UninterpretedOption::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.name_.~RepeatedPtrField();
+ _impl_.identifier_value_.Destroy();
+ _impl_.string_value_.Destroy();
+ _impl_.aggregate_value_.Destroy();
+}
+
+void UninterpretedOption::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void UninterpretedOption::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.name_.Clear();
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000007u) {
+ if (cached_has_bits & 0x00000001u) {
+ _impl_.identifier_value_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _impl_.string_value_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _impl_.aggregate_value_.ClearNonDefaultToEmpty();
+ }
+ }
+ if (cached_has_bits & 0x00000038u) {
+ ::memset(&_impl_.positive_int_value_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.double_value_) -
+ reinterpret_cast<char*>(&_impl_.positive_int_value_)) + sizeof(_impl_.double_value_));
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* UninterpretedOption::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.UninterpretedOption.identifier_value");
+ #endif // !NDEBUG
+ } 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);
+ _impl_.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);
+ _impl_.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);
+ _impl_.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 = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.UninterpretedOption.aggregate_value");
+ #endif // !NDEBUG
+ } 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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_name_size()); i < n; i++) {
+ const auto& repfield = this->_internal_name(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ cached_has_bits = _impl_._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 = ::_pbi::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 = ::_pbi::WireFormatLite::WriteInt64ToArray(5, this->_internal_negative_int_value(), target);
+ }
+
+ // optional double double_value = 6;
+ if (cached_has_bits & 0x00000020u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::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 = ::_pbi::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;
+
+ uint32_t 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->_impl_.name_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _impl_._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 += ::_pbi::WireFormatLite::UInt64SizePlusOne(this->_internal_positive_int_value());
+ }
+
+ // optional int64 negative_int_value = 5;
+ if (cached_has_bits & 0x00000010u) {
+ total_size += ::_pbi::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, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UninterpretedOption::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ UninterpretedOption::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UninterpretedOption::GetClassData() const { return &_class_data_; }
+
+
+void UninterpretedOption::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<UninterpretedOption*>(&to_msg);
+ auto& from = static_cast<const UninterpretedOption&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.name_.MergeFrom(from._impl_.name_);
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x0000003fu) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_set_identifier_value(from._internal_identifier_value());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_internal_set_string_value(from._internal_string_value());
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _this->_internal_set_aggregate_value(from._internal_aggregate_value());
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _this->_impl_.positive_int_value_ = from._impl_.positive_int_value_;
+ }
+ if (cached_has_bits & 0x00000010u) {
+ _this->_impl_.negative_int_value_ = from._impl_.negative_int_value_;
+ }
+ if (cached_has_bits & 0x00000020u) {
+ _this->_impl_.double_value_ = from._impl_.double_value_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_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(_impl_.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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.name_.InternalSwap(&other->_impl_.name_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.identifier_value_, lhs_arena,
+ &other->_impl_.identifier_value_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.string_value_, lhs_arena,
+ &other->_impl_.string_value_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.aggregate_value_, lhs_arena,
+ &other->_impl_.aggregate_value_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_.double_value_)
+ + sizeof(UninterpretedOption::_impl_.double_value_)
+ - PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_.positive_int_value_)>(
+ reinterpret_cast<char*>(&_impl_.positive_int_value_),
+ reinterpret_cast<char*>(&other->_impl_.positive_int_value_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata UninterpretedOption::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo.Location)
+}
+SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ SourceCodeInfo_Location* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.path_){from._impl_.path_}
+ , /*decltype(_impl_._path_cached_byte_size_)*/{0}
+ , decltype(_impl_.span_){from._impl_.span_}
+ , /*decltype(_impl_._span_cached_byte_size_)*/{0}
+ , decltype(_impl_.leading_detached_comments_){from._impl_.leading_detached_comments_}
+ , decltype(_impl_.leading_comments_){}
+ , decltype(_impl_.trailing_comments_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.leading_comments_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.leading_comments_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_leading_comments()) {
+ _this->_impl_.leading_comments_.Set(from._internal_leading_comments(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.trailing_comments_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.trailing_comments_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_trailing_comments()) {
+ _this->_impl_.trailing_comments_.Set(from._internal_trailing_comments(),
+ _this->GetArenaForAllocation());
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo.Location)
+}
+
+inline void SourceCodeInfo_Location::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.path_){arena}
+ , /*decltype(_impl_._path_cached_byte_size_)*/{0}
+ , decltype(_impl_.span_){arena}
+ , /*decltype(_impl_._span_cached_byte_size_)*/{0}
+ , decltype(_impl_.leading_detached_comments_){arena}
+ , decltype(_impl_.leading_comments_){}
+ , decltype(_impl_.trailing_comments_){}
+ };
+ _impl_.leading_comments_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.leading_comments_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.trailing_comments_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.trailing_comments_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+SourceCodeInfo_Location::~SourceCodeInfo_Location() {
+ // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo.Location)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void SourceCodeInfo_Location::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.path_.~RepeatedField();
+ _impl_.span_.~RepeatedField();
+ _impl_.leading_detached_comments_.~RepeatedPtrField();
+ _impl_.leading_comments_.Destroy();
+ _impl_.trailing_comments_.Destroy();
+}
+
+void SourceCodeInfo_Location::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void SourceCodeInfo_Location::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo.Location)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.path_.Clear();
+ _impl_.span_.Clear();
+ _impl_.leading_detached_comments_.Clear();
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _impl_.leading_comments_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _impl_.trailing_comments_.ClearNonDefaultToEmpty();
+ }
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* SourceCodeInfo_Location::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.leading_comments");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.trailing_comments");
+ #endif // !NDEBUG
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
+ #endif // !NDEBUG
+ 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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated int32 path = 1 [packed = true];
+ {
+ int byte_size = _impl_._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 = _impl_._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 = _impl_._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 = ::_pbi::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;
+
+ uint32_t 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 = ::_pbi::WireFormatLite::
+ Int32Size(this->_impl_.path_);
+ if (data_size > 0) {
+ total_size += 1 +
+ ::_pbi::WireFormatLite::Int32Size(static_cast<int32_t>(data_size));
+ }
+ int cached_size = ::_pbi::ToCachedSize(data_size);
+ _impl_._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 = ::_pbi::WireFormatLite::
+ Int32Size(this->_impl_.span_);
+ if (data_size > 0) {
+ total_size += 1 +
+ ::_pbi::WireFormatLite::Int32Size(static_cast<int32_t>(data_size));
+ }
+ int cached_size = ::_pbi::ToCachedSize(data_size);
+ _impl_._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(_impl_.leading_detached_comments_.size());
+ for (int i = 0, n = _impl_.leading_detached_comments_.size(); i < n; i++) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ _impl_.leading_detached_comments_.Get(i));
+ }
+
+ cached_has_bits = _impl_._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, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceCodeInfo_Location::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ 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_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<SourceCodeInfo_Location*>(&to_msg);
+ auto& from = static_cast<const SourceCodeInfo_Location&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo.Location)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.path_.MergeFrom(from._impl_.path_);
+ _this->_impl_.span_.MergeFrom(from._impl_.span_);
+ _this->_impl_.leading_detached_comments_.MergeFrom(from._impl_.leading_detached_comments_);
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_set_leading_comments(from._internal_leading_comments());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_internal_set_trailing_comments(from._internal_trailing_comments());
+ }
+ }
+ _this->_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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.path_.InternalSwap(&other->_impl_.path_);
+ _impl_.span_.InternalSwap(&other->_impl_.span_);
+ _impl_.leading_detached_comments_.InternalSwap(&other->_impl_.leading_detached_comments_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.leading_comments_, lhs_arena,
+ &other->_impl_.leading_comments_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.trailing_comments_, lhs_arena,
+ &other->_impl_.trailing_comments_, rhs_arena
+ );
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata SourceCodeInfo_Location::GetMetadata() const {
+ return ::_pbi::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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo)
+}
+SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ SourceCodeInfo* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.location_){from._impl_.location_}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo)
+}
+
+inline void SourceCodeInfo::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.location_){arena}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+SourceCodeInfo::~SourceCodeInfo() {
+ // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void SourceCodeInfo::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.location_.~RepeatedPtrField();
+}
+
+void SourceCodeInfo::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void SourceCodeInfo::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.location_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* SourceCodeInfo::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_location_size()); i < n; i++) {
+ const auto& repfield = this->_internal_location(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(1, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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->_impl_.location_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceCodeInfo::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ SourceCodeInfo::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*SourceCodeInfo::GetClassData() const { return &_class_data_; }
+
+
+void SourceCodeInfo::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<SourceCodeInfo*>(&to_msg);
+ auto& from = static_cast<const SourceCodeInfo&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.location_.MergeFrom(from._impl_.location_);
+ _this->_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_);
+ _impl_.location_.InternalSwap(&other->_impl_.location_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata SourceCodeInfo::GetMetadata() const {
+ return ::_pbi::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>()._impl_._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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo.Annotation)
+}
+GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ GeneratedCodeInfo_Annotation* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){from._impl_._has_bits_}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.path_){from._impl_.path_}
+ , /*decltype(_impl_._path_cached_byte_size_)*/{0}
+ , decltype(_impl_.source_file_){}
+ , decltype(_impl_.begin_){}
+ , decltype(_impl_.end_){}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.source_file_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.source_file_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_source_file()) {
+ _this->_impl_.source_file_.Set(from._internal_source_file(),
+ _this->GetArenaForAllocation());
+ }
+ ::memcpy(&_impl_.begin_, &from._impl_.begin_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.end_) -
+ reinterpret_cast<char*>(&_impl_.begin_)) + sizeof(_impl_.end_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo.Annotation)
+}
+
+inline void GeneratedCodeInfo_Annotation::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_._has_bits_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , decltype(_impl_.path_){arena}
+ , /*decltype(_impl_._path_cached_byte_size_)*/{0}
+ , decltype(_impl_.source_file_){}
+ , decltype(_impl_.begin_){0}
+ , decltype(_impl_.end_){0}
+ };
+ _impl_.source_file_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.source_file_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+GeneratedCodeInfo_Annotation::~GeneratedCodeInfo_Annotation() {
+ // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo.Annotation)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void GeneratedCodeInfo_Annotation::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.path_.~RepeatedField();
+ _impl_.source_file_.Destroy();
+}
+
+void GeneratedCodeInfo_Annotation::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void GeneratedCodeInfo_Annotation::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.path_.Clear();
+ cached_has_bits = _impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000001u) {
+ _impl_.source_file_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000006u) {
+ ::memset(&_impl_.begin_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.end_) -
+ reinterpret_cast<char*>(&_impl_.begin_)) + sizeof(_impl_.end_));
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* GeneratedCodeInfo_Annotation::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ #ifndef NDEBUG
+ ::_pbi::VerifyUTF8(str, "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
+ #endif // !NDEBUG
+ } 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);
+ _impl_.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);
+ _impl_.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:
+ _impl_._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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated int32 path = 1 [packed = true];
+ {
+ int byte_size = _impl_._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 = _impl_._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 = ::_pbi::WireFormatLite::WriteInt32ToArray(3, this->_internal_begin(), target);
+ }
+
+ // optional int32 end = 4;
+ if (cached_has_bits & 0x00000004u) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteInt32ToArray(4, this->_internal_end(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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 = ::_pbi::WireFormatLite::
+ Int32Size(this->_impl_.path_);
+ if (data_size > 0) {
+ total_size += 1 +
+ ::_pbi::WireFormatLite::Int32Size(static_cast<int32_t>(data_size));
+ }
+ int cached_size = ::_pbi::ToCachedSize(data_size);
+ _impl_._path_cached_byte_size_.store(cached_size,
+ std::memory_order_relaxed);
+ total_size += data_size;
+ }
+
+ cached_has_bits = _impl_._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 += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_begin());
+ }
+
+ // optional int32 end = 4;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_end());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData GeneratedCodeInfo_Annotation::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ 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_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<GeneratedCodeInfo_Annotation*>(&to_msg);
+ auto& from = static_cast<const GeneratedCodeInfo_Annotation&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.path_.MergeFrom(from._impl_.path_);
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (cached_has_bits & 0x00000007u) {
+ if (cached_has_bits & 0x00000001u) {
+ _this->_internal_set_source_file(from._internal_source_file());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _this->_impl_.begin_ = from._impl_.begin_;
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _this->_impl_.end_ = from._impl_.end_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ }
+ _this->_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(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.path_.InternalSwap(&other->_impl_.path_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.source_file_, lhs_arena,
+ &other->_impl_.source_file_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_.end_)
+ + sizeof(GeneratedCodeInfo_Annotation::_impl_.end_)
+ - PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_.begin_)>(
+ reinterpret_cast<char*>(&_impl_.begin_),
+ reinterpret_cast<char*>(&other->_impl_.begin_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata GeneratedCodeInfo_Annotation::GetMetadata() const {
+ return ::_pbi::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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo)
+}
+GeneratedCodeInfo::GeneratedCodeInfo(const GeneratedCodeInfo& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ GeneratedCodeInfo* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.annotation_){from._impl_.annotation_}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo)
+}
+
+inline void GeneratedCodeInfo::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.annotation_){arena}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+GeneratedCodeInfo::~GeneratedCodeInfo() {
+ // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void GeneratedCodeInfo::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.annotation_.~RepeatedPtrField();
+}
+
+void GeneratedCodeInfo::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void GeneratedCodeInfo::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.annotation_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* GeneratedCodeInfo::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_annotation_size()); i < n; i++) {
+ const auto& repfield = this->_internal_annotation(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(1, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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->_impl_.annotation_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData GeneratedCodeInfo::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ GeneratedCodeInfo::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GeneratedCodeInfo::GetClassData() const { return &_class_data_; }
+
+
+void GeneratedCodeInfo::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<GeneratedCodeInfo*>(&to_msg);
+ auto& from = static_cast<const GeneratedCodeInfo&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.annotation_.MergeFrom(from._impl_.annotation_);
+ _this->_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_);
+ _impl_.annotation_.InternalSwap(&other->_impl_.annotation_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata GeneratedCodeInfo::GetMetadata() const {
+ return ::_pbi::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/toolkit/components/protobuf/src/google/protobuf/descriptor.pb.h b/toolkit/components/protobuf/src/google/protobuf/descriptor.pb.h
new file mode 100644
index 0000000000..2d9c790f57
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/descriptor.pb.h
@@ -0,0 +1,14821 @@
+// 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 < 3021000
+#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 3021006 < 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_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 uint32_t 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 std::string& FieldDescriptorProto_Type_Name(T enum_t_value) {
+ static_assert(::std::is_same<T, FieldDescriptorProto_Type>::value ||
+ ::std::is_integral<T>::value,
+ "Incorrect type passed to function FieldDescriptorProto_Type_Name.");
+ return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
+ FieldDescriptorProto_Type_descriptor(), enum_t_value);
+}
+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 std::string& FieldDescriptorProto_Label_Name(T enum_t_value) {
+ static_assert(::std::is_same<T, FieldDescriptorProto_Label>::value ||
+ ::std::is_integral<T>::value,
+ "Incorrect type passed to function FieldDescriptorProto_Label_Name.");
+ return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
+ FieldDescriptorProto_Label_descriptor(), enum_t_value);
+}
+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 std::string& FileOptions_OptimizeMode_Name(T enum_t_value) {
+ static_assert(::std::is_same<T, FileOptions_OptimizeMode>::value ||
+ ::std::is_integral<T>::value,
+ "Incorrect type passed to function FileOptions_OptimizeMode_Name.");
+ return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
+ FileOptions_OptimizeMode_descriptor(), enum_t_value);
+}
+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 std::string& FieldOptions_CType_Name(T enum_t_value) {
+ static_assert(::std::is_same<T, FieldOptions_CType>::value ||
+ ::std::is_integral<T>::value,
+ "Incorrect type passed to function FieldOptions_CType_Name.");
+ return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
+ FieldOptions_CType_descriptor(), enum_t_value);
+}
+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 std::string& FieldOptions_JSType_Name(T enum_t_value) {
+ static_assert(::std::is_same<T, FieldOptions_JSType>::value ||
+ ::std::is_integral<T>::value,
+ "Incorrect type passed to function FieldOptions_JSType_Name.");
+ return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
+ FieldOptions_JSType_descriptor(), enum_t_value);
+}
+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 std::string& MethodOptions_IdempotencyLevel_Name(T enum_t_value) {
+ static_assert(::std::is_same<T, MethodOptions_IdempotencyLevel>::value ||
+ ::std::is_integral<T>::value,
+ "Incorrect type passed to function MethodOptions_IdempotencyLevel_Name.");
+ return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
+ MethodOptions_IdempotencyLevel_descriptor(), enum_t_value);
+}
+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 PROTOBUF_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) {
+ FileDescriptorSet::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto > file_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ FileDescriptorProto::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& dependency(int index) const;
+ std::string* mutable_dependency(int index);
+ void set_dependency(int index, const std::string& value);
+ void set_dependency(int index, std::string&& value);
+ void set_dependency(int index, const char* value);
+ void set_dependency(int index, const char* value, size_t size);
+ std::string* add_dependency();
+ void add_dependency(const std::string& value);
+ void add_dependency(std::string&& value);
+ void add_dependency(const char* value);
+ void add_dependency(const char* value, size_t size);
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& dependency() const;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_dependency();
+ private:
+ const std::string& _internal_dependency(int index) const;
+ std::string* _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:
+ int32_t _internal_public_dependency(int index) const;
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+ _internal_public_dependency() const;
+ void _internal_add_public_dependency(int32_t value);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+ _internal_mutable_public_dependency();
+ public:
+ int32_t public_dependency(int index) const;
+ void set_public_dependency(int index, int32_t value);
+ void add_public_dependency(int32_t value);
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+ public_dependency() const;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+ 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:
+ int32_t _internal_weak_dependency(int index) const;
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+ _internal_weak_dependency() const;
+ void _internal_add_weak_dependency(int32_t value);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+ _internal_mutable_weak_dependency();
+ public:
+ int32_t weak_dependency(int index) const;
+ void set_weak_dependency(int index, int32_t value);
+ void add_weak_dependency(int32_t value);
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+ weak_dependency() const;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+ mutable_weak_dependency();
+
+ // optional string name = 1;
+ bool has_name() const;
+ private:
+ bool _internal_has_name() const;
+ public:
+ void clear_name();
+ const std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _internal_mutable_name();
+ public:
+
+ // optional string package = 2;
+ bool has_package() const;
+ private:
+ bool _internal_has_package() const;
+ public:
+ void clear_package();
+ const std::string& package() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_package(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_package();
+ PROTOBUF_NODISCARD std::string* release_package();
+ void set_allocated_package(std::string* package);
+ private:
+ const std::string& _internal_package() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_package(const std::string& value);
+ std::string* _internal_mutable_package();
+ public:
+
+ // optional string syntax = 12;
+ bool has_syntax() const;
+ private:
+ bool _internal_has_syntax() const;
+ public:
+ void clear_syntax();
+ const std::string& syntax() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_syntax(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_syntax();
+ PROTOBUF_NODISCARD std::string* release_syntax();
+ void set_allocated_syntax(std::string* syntax);
+ private:
+ const std::string& _internal_syntax() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_syntax(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> 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< int32_t > public_dependency_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t > 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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ DescriptorProto_ExtensionRange::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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();
+ int32_t start() const;
+ void set_start(int32_t value);
+ private:
+ int32_t _internal_start() const;
+ void _internal_set_start(int32_t value);
+ public:
+
+ // optional int32 end = 2;
+ bool has_end() const;
+ private:
+ bool _internal_has_end() const;
+ public:
+ void clear_end();
+ int32_t end() const;
+ void set_end(int32_t value);
+ private:
+ int32_t _internal_end() const;
+ void _internal_set_end(int32_t 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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options_;
+ int32_t start_;
+ int32_t end_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ DescriptorProto_ReservedRange::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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();
+ int32_t start() const;
+ void set_start(int32_t value);
+ private:
+ int32_t _internal_start() const;
+ void _internal_set_start(int32_t value);
+ public:
+
+ // optional int32 end = 2;
+ bool has_end() const;
+ private:
+ bool _internal_has_end() const;
+ public:
+ void clear_end();
+ int32_t end() const;
+ void set_end(int32_t value);
+ private:
+ int32_t _internal_end() const;
+ void _internal_set_end(int32_t 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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ int32_t start_;
+ int32_t end_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ DescriptorProto::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& reserved_name(int index) const;
+ std::string* mutable_reserved_name(int index);
+ void set_reserved_name(int index, const std::string& value);
+ void set_reserved_name(int index, std::string&& value);
+ void set_reserved_name(int index, const char* value);
+ void set_reserved_name(int index, const char* value, size_t size);
+ std::string* add_reserved_name();
+ void add_reserved_name(const std::string& value);
+ void add_reserved_name(std::string&& value);
+ void add_reserved_name(const char* value);
+ void add_reserved_name(const char* value, size_t size);
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& reserved_name() const;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_reserved_name();
+ private:
+ const std::string& _internal_reserved_name(int index) const;
+ std::string* _internal_add_reserved_name();
+ public:
+
+ // optional string name = 1;
+ bool has_name() const;
+ private:
+ bool _internal_has_name() const;
+ public:
+ void clear_name();
+ const std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::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<std::string> reserved_name_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ ::PROTOBUF_NAMESPACE_ID::MessageOptions* options_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ ExtensionRangeOptions::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 _impl_._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) {
+ _impl_._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 _impl_._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(), _impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._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, &_impl_._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, &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.ExtensionRangeOptions)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ FieldDescriptorProto::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& 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 std::string& 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 std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _internal_mutable_name();
+ public:
+
+ // optional string extendee = 2;
+ bool has_extendee() const;
+ private:
+ bool _internal_has_extendee() const;
+ public:
+ void clear_extendee();
+ const std::string& extendee() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_extendee(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_extendee();
+ PROTOBUF_NODISCARD std::string* release_extendee();
+ void set_allocated_extendee(std::string* extendee);
+ private:
+ const std::string& _internal_extendee() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_extendee(const std::string& value);
+ std::string* _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 std::string& type_name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_type_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_type_name();
+ PROTOBUF_NODISCARD std::string* release_type_name();
+ void set_allocated_type_name(std::string* type_name);
+ private:
+ const std::string& _internal_type_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_type_name(const std::string& value);
+ std::string* _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 std::string& default_value() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_default_value(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_default_value();
+ PROTOBUF_NODISCARD std::string* release_default_value();
+ void set_allocated_default_value(std::string* default_value);
+ private:
+ const std::string& _internal_default_value() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_default_value(const std::string& value);
+ std::string* _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 std::string& json_name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_json_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_json_name();
+ PROTOBUF_NODISCARD std::string* release_json_name();
+ void set_allocated_json_name(std::string* json_name);
+ private:
+ const std::string& _internal_json_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_json_name(const std::string& value);
+ std::string* _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();
+ int32_t number() const;
+ void set_number(int32_t value);
+ private:
+ int32_t _internal_number() const;
+ void _internal_set_number(int32_t value);
+ public:
+
+ // optional int32 oneof_index = 9;
+ bool has_oneof_index() const;
+ private:
+ bool _internal_has_oneof_index() const;
+ public:
+ void clear_oneof_index();
+ int32_t oneof_index() const;
+ void set_oneof_index(int32_t value);
+ private:
+ int32_t _internal_oneof_index() const;
+ void _internal_set_oneof_index(int32_t 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_;
+ struct Impl_ {
+ ::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_;
+ int32_t number_;
+ int32_t oneof_index_;
+ bool proto3_optional_;
+ int label_;
+ int type_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ OneofDescriptorProto::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ EnumDescriptorProto_EnumReservedRange::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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();
+ int32_t start() const;
+ void set_start(int32_t value);
+ private:
+ int32_t _internal_start() const;
+ void _internal_set_start(int32_t value);
+ public:
+
+ // optional int32 end = 2;
+ bool has_end() const;
+ private:
+ bool _internal_has_end() const;
+ public:
+ void clear_end();
+ int32_t end() const;
+ void set_end(int32_t value);
+ private:
+ int32_t _internal_end() const;
+ void _internal_set_end(int32_t 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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ int32_t start_;
+ int32_t end_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ EnumDescriptorProto::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& reserved_name(int index) const;
+ std::string* mutable_reserved_name(int index);
+ void set_reserved_name(int index, const std::string& value);
+ void set_reserved_name(int index, std::string&& value);
+ void set_reserved_name(int index, const char* value);
+ void set_reserved_name(int index, const char* value, size_t size);
+ std::string* add_reserved_name();
+ void add_reserved_name(const std::string& value);
+ void add_reserved_name(std::string&& value);
+ void add_reserved_name(const char* value);
+ void add_reserved_name(const char* value, size_t size);
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& reserved_name() const;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_reserved_name();
+ private:
+ const std::string& _internal_reserved_name(int index) const;
+ std::string* _internal_add_reserved_name();
+ public:
+
+ // optional string name = 1;
+ bool has_name() const;
+ private:
+ bool _internal_has_name() const;
+ public:
+ void clear_name();
+ const std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::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<std::string> reserved_name_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ ::PROTOBUF_NAMESPACE_ID::EnumOptions* options_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ EnumValueDescriptorProto::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _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();
+ int32_t number() const;
+ void set_number(int32_t value);
+ private:
+ int32_t _internal_number() const;
+ void _internal_set_number(int32_t 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_;
+ struct Impl_ {
+ ::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_;
+ int32_t number_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ ServiceDescriptorProto::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ MethodDescriptorProto::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _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 std::string& input_type() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_input_type(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_input_type();
+ PROTOBUF_NODISCARD std::string* release_input_type();
+ void set_allocated_input_type(std::string* input_type);
+ private:
+ const std::string& _internal_input_type() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_input_type(const std::string& value);
+ std::string* _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 std::string& output_type() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_output_type(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_output_type();
+ PROTOBUF_NODISCARD std::string* release_output_type();
+ void set_allocated_output_type(std::string* output_type);
+ private:
+ const std::string& _internal_output_type() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_output_type(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ FileOptions::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& 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 std::string& java_package() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_java_package(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_java_package();
+ PROTOBUF_NODISCARD std::string* release_java_package();
+ void set_allocated_java_package(std::string* java_package);
+ private:
+ const std::string& _internal_java_package() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_java_package(const std::string& value);
+ std::string* _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 std::string& java_outer_classname() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_java_outer_classname(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_java_outer_classname();
+ PROTOBUF_NODISCARD std::string* release_java_outer_classname();
+ void set_allocated_java_outer_classname(std::string* java_outer_classname);
+ private:
+ const std::string& _internal_java_outer_classname() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_java_outer_classname(const std::string& value);
+ std::string* _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 std::string& go_package() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_go_package(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_go_package();
+ PROTOBUF_NODISCARD std::string* release_go_package();
+ void set_allocated_go_package(std::string* go_package);
+ private:
+ const std::string& _internal_go_package() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_go_package(const std::string& value);
+ std::string* _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 std::string& objc_class_prefix() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_objc_class_prefix(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_objc_class_prefix();
+ PROTOBUF_NODISCARD std::string* release_objc_class_prefix();
+ void set_allocated_objc_class_prefix(std::string* objc_class_prefix);
+ private:
+ const std::string& _internal_objc_class_prefix() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_objc_class_prefix(const std::string& value);
+ std::string* _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 std::string& csharp_namespace() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_csharp_namespace(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_csharp_namespace();
+ PROTOBUF_NODISCARD std::string* release_csharp_namespace();
+ void set_allocated_csharp_namespace(std::string* csharp_namespace);
+ private:
+ const std::string& _internal_csharp_namespace() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_csharp_namespace(const std::string& value);
+ std::string* _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 std::string& swift_prefix() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_swift_prefix(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_swift_prefix();
+ PROTOBUF_NODISCARD std::string* release_swift_prefix();
+ void set_allocated_swift_prefix(std::string* swift_prefix);
+ private:
+ const std::string& _internal_swift_prefix() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_swift_prefix(const std::string& value);
+ std::string* _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 std::string& php_class_prefix() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_php_class_prefix(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_php_class_prefix();
+ PROTOBUF_NODISCARD std::string* release_php_class_prefix();
+ void set_allocated_php_class_prefix(std::string* php_class_prefix);
+ private:
+ const std::string& _internal_php_class_prefix() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_php_class_prefix(const std::string& value);
+ std::string* _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 std::string& php_namespace() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_php_namespace(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_php_namespace();
+ PROTOBUF_NODISCARD std::string* release_php_namespace();
+ void set_allocated_php_namespace(std::string* php_namespace);
+ private:
+ const std::string& _internal_php_namespace() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_php_namespace(const std::string& value);
+ std::string* _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 std::string& php_metadata_namespace() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_php_metadata_namespace(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_php_metadata_namespace();
+ PROTOBUF_NODISCARD std::string* release_php_metadata_namespace();
+ void set_allocated_php_metadata_namespace(std::string* php_metadata_namespace);
+ private:
+ const std::string& _internal_php_metadata_namespace() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_php_metadata_namespace(const std::string& value);
+ std::string* _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 std::string& ruby_package() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_ruby_package(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_ruby_package();
+ PROTOBUF_NODISCARD std::string* release_ruby_package();
+ void set_allocated_ruby_package(std::string* ruby_package);
+ private:
+ const std::string& _internal_ruby_package() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_ruby_package(const std::string& value);
+ std::string* _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 _impl_._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) {
+ _impl_._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 _impl_._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(), _impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._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, &_impl_._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, &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ MessageOptions::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 _impl_._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) {
+ _impl_._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 _impl_._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(), _impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._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, &_impl_._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, &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ FieldOptions::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& 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 std::string& 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,
+ kJstypeFieldNumber = 6,
+ kPackedFieldNumber = 2,
+ kLazyFieldNumber = 5,
+ kUnverifiedLazyFieldNumber = 15,
+ kDeprecatedFieldNumber = 3,
+ kWeakFieldNumber = 10,
+ };
+ // 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 .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:
+
+ // 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 unverified_lazy = 15 [default = false];
+ bool has_unverified_lazy() const;
+ private:
+ bool _internal_has_unverified_lazy() const;
+ public:
+ void clear_unverified_lazy();
+ bool unverified_lazy() const;
+ void set_unverified_lazy(bool value);
+ private:
+ bool _internal_unverified_lazy() const;
+ void _internal_set_unverified_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:
+
+
+ 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 _impl_._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) {
+ _impl_._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 _impl_._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(), _impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._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, &_impl_._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, &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ ::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_;
+ int jstype_;
+ bool packed_;
+ bool lazy_;
+ bool unverified_lazy_;
+ bool deprecated_;
+ bool weak_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ OneofOptions::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 _impl_._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) {
+ _impl_._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 _impl_._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(), _impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._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, &_impl_._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, &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.OneofOptions)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ EnumOptions::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 _impl_._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) {
+ _impl_._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 _impl_._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(), _impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._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, &_impl_._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, &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ EnumValueOptions::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 _impl_._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) {
+ _impl_._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 _impl_._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(), _impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._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, &_impl_._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, &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ ServiceOptions::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 _impl_._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) {
+ _impl_._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 _impl_._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(), _impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._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, &_impl_._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, &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ MethodOptions::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& 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 _impl_._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) {
+ _impl_._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 _impl_._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(), _impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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, &_impl_._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,
+ &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._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, &_impl_._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, &_impl_._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,
+ &_impl_._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(), _impl_._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, &_impl_._extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ UninterpretedOption_NamePart::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& name_part() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name_part(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name_part();
+ PROTOBUF_NODISCARD std::string* release_name_part();
+ void set_allocated_name_part(std::string* name_part);
+ private:
+ const std::string& _internal_name_part() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name_part(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ UninterpretedOption::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& identifier_value() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_identifier_value(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_identifier_value();
+ PROTOBUF_NODISCARD std::string* release_identifier_value();
+ void set_allocated_identifier_value(std::string* identifier_value);
+ private:
+ const std::string& _internal_identifier_value() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_identifier_value(const std::string& value);
+ std::string* _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 std::string& string_value() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_string_value(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_string_value();
+ PROTOBUF_NODISCARD std::string* release_string_value();
+ void set_allocated_string_value(std::string* string_value);
+ private:
+ const std::string& _internal_string_value() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_string_value(const std::string& value);
+ std::string* _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 std::string& aggregate_value() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_aggregate_value(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_aggregate_value();
+ PROTOBUF_NODISCARD std::string* release_aggregate_value();
+ void set_allocated_aggregate_value(std::string* aggregate_value);
+ private:
+ const std::string& _internal_aggregate_value() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_aggregate_value(const std::string& value);
+ std::string* _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();
+ uint64_t positive_int_value() const;
+ void set_positive_int_value(uint64_t value);
+ private:
+ uint64_t _internal_positive_int_value() const;
+ void _internal_set_positive_int_value(uint64_t 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();
+ int64_t negative_int_value() const;
+ void set_negative_int_value(int64_t value);
+ private:
+ int64_t _internal_negative_int_value() const;
+ void _internal_set_negative_int_value(int64_t 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_;
+ struct Impl_ {
+ ::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_;
+ uint64_t positive_int_value_;
+ int64_t negative_int_value_;
+ double double_value_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ SourceCodeInfo_Location::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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:
+ int32_t _internal_path(int index) const;
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+ _internal_path() const;
+ void _internal_add_path(int32_t value);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+ _internal_mutable_path();
+ public:
+ int32_t path(int index) const;
+ void set_path(int index, int32_t value);
+ void add_path(int32_t value);
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+ path() const;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+ mutable_path();
+
+ // repeated int32 span = 2 [packed = true];
+ int span_size() const;
+ private:
+ int _internal_span_size() const;
+ public:
+ void clear_span();
+ private:
+ int32_t _internal_span(int index) const;
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+ _internal_span() const;
+ void _internal_add_span(int32_t value);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+ _internal_mutable_span();
+ public:
+ int32_t span(int index) const;
+ void set_span(int index, int32_t value);
+ void add_span(int32_t value);
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+ span() const;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+ 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 std::string& leading_detached_comments(int index) const;
+ std::string* mutable_leading_detached_comments(int index);
+ void set_leading_detached_comments(int index, const std::string& value);
+ void set_leading_detached_comments(int index, std::string&& value);
+ void set_leading_detached_comments(int index, const char* value);
+ void set_leading_detached_comments(int index, const char* value, size_t size);
+ std::string* add_leading_detached_comments();
+ void add_leading_detached_comments(const std::string& value);
+ void add_leading_detached_comments(std::string&& 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<std::string>& leading_detached_comments() const;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_leading_detached_comments();
+ private:
+ const std::string& _internal_leading_detached_comments(int index) const;
+ std::string* _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 std::string& leading_comments() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_leading_comments(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_leading_comments();
+ PROTOBUF_NODISCARD std::string* release_leading_comments();
+ void set_allocated_leading_comments(std::string* leading_comments);
+ private:
+ const std::string& _internal_leading_comments() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_leading_comments(const std::string& value);
+ std::string* _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 std::string& trailing_comments() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_trailing_comments(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_trailing_comments();
+ PROTOBUF_NODISCARD std::string* release_trailing_comments();
+ void set_allocated_trailing_comments(std::string* trailing_comments);
+ private:
+ const std::string& _internal_trailing_comments() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_trailing_comments(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t > path_;
+ mutable std::atomic<int> _path_cached_byte_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t > span_;
+ mutable std::atomic<int> _span_cached_byte_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> leading_detached_comments_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr leading_comments_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr trailing_comments_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ SourceCodeInfo::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location > location_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ GeneratedCodeInfo_Annotation::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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:
+ int32_t _internal_path(int index) const;
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+ _internal_path() const;
+ void _internal_add_path(int32_t value);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+ _internal_mutable_path();
+ public:
+ int32_t path(int index) const;
+ void set_path(int index, int32_t value);
+ void add_path(int32_t value);
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+ path() const;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+ 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 std::string& source_file() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_source_file(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_source_file();
+ PROTOBUF_NODISCARD std::string* release_source_file();
+ void set_allocated_source_file(std::string* source_file);
+ private:
+ const std::string& _internal_source_file() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_source_file(const std::string& value);
+ std::string* _internal_mutable_source_file();
+ public:
+
+ // optional int32 begin = 3;
+ bool has_begin() const;
+ private:
+ bool _internal_has_begin() const;
+ public:
+ void clear_begin();
+ int32_t begin() const;
+ void set_begin(int32_t value);
+ private:
+ int32_t _internal_begin() const;
+ void _internal_set_begin(int32_t value);
+ public:
+
+ // optional int32 end = 4;
+ bool has_end() const;
+ private:
+ bool _internal_has_end() const;
+ public:
+ void clear_end();
+ int32_t end() const;
+ void set_end(int32_t value);
+ private:
+ int32_t _internal_end() const;
+ void _internal_set_end(int32_t 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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t > path_;
+ mutable std::atomic<int> _path_cached_byte_size_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr source_file_;
+ int32_t begin_;
+ int32_t end_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ GeneratedCodeInfo::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation > annotation_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 _impl_.file_.size();
+}
+inline int FileDescriptorSet::file_size() const {
+ return _internal_file_size();
+}
+inline void FileDescriptorSet::clear_file() {
+ _impl_.file_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorSet.file)
+ return _impl_.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 &_impl_.file_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& FileDescriptorSet::_internal_file(int index) const {
+ return _impl_.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 _impl_.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 _impl_.file_;
+}
+
+// -------------------------------------------------------------------
+
+// FileDescriptorProto
+
+// optional string name = 1;
+inline bool FileDescriptorProto::_internal_has_name() const {
+ bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool FileDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void FileDescriptorProto::clear_name() {
+ _impl_.name_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.name)
+}
+inline std::string* FileDescriptorProto::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.name)
+ return _s;
+}
+inline const std::string& FileDescriptorProto::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void FileDescriptorProto::_internal_set_name(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FileDescriptorProto::_internal_mutable_name() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FileDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ auto* p = _impl_.name_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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 = (_impl_._has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool FileDescriptorProto::has_package() const {
+ return _internal_has_package();
+}
+inline void FileDescriptorProto::clear_package() {
+ _impl_.package_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.package_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.package)
+}
+inline std::string* FileDescriptorProto::mutable_package() {
+ std::string* _s = _internal_mutable_package();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.package)
+ return _s;
+}
+inline const std::string& FileDescriptorProto::_internal_package() const {
+ return _impl_.package_.Get();
+}
+inline void FileDescriptorProto::_internal_set_package(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.package_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FileDescriptorProto::_internal_mutable_package() {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ return _impl_.package_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FileDescriptorProto::release_package() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.package)
+ if (!_internal_has_package()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ auto* p = _impl_.package_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.package_.IsDefault()) {
+ _impl_.package_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileDescriptorProto::set_allocated_package(std::string* package) {
+ if (package != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ _impl_.package_.SetAllocated(package, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.package_.IsDefault()) {
+ _impl_.package_.Set("", 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 _impl_.dependency_.size();
+}
+inline int FileDescriptorProto::dependency_size() const {
+ return _internal_dependency_size();
+}
+inline void FileDescriptorProto::clear_dependency() {
+ _impl_.dependency_.Clear();
+}
+inline std::string* FileDescriptorProto::add_dependency() {
+ std::string* _s = _internal_add_dependency();
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.FileDescriptorProto.dependency)
+ return _s;
+}
+inline const std::string& FileDescriptorProto::_internal_dependency(int index) const {
+ return _impl_.dependency_.Get(index);
+}
+inline const std::string& FileDescriptorProto::dependency(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.dependency)
+ return _internal_dependency(index);
+}
+inline std::string* FileDescriptorProto::mutable_dependency(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.dependency)
+ return _impl_.dependency_.Mutable(index);
+}
+inline void FileDescriptorProto::set_dependency(int index, const std::string& value) {
+ _impl_.dependency_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
+}
+inline void FileDescriptorProto::set_dependency(int index, std::string&& value) {
+ _impl_.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);
+ _impl_.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) {
+ _impl_.dependency_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.dependency)
+}
+inline std::string* FileDescriptorProto::_internal_add_dependency() {
+ return _impl_.dependency_.Add();
+}
+inline void FileDescriptorProto::add_dependency(const std::string& value) {
+ _impl_.dependency_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
+}
+inline void FileDescriptorProto::add_dependency(std::string&& value) {
+ _impl_.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);
+ _impl_.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) {
+ _impl_.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<std::string>&
+FileDescriptorProto::dependency() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.dependency)
+ return _impl_.dependency_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
+FileDescriptorProto::mutable_dependency() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.dependency)
+ return &_impl_.dependency_;
+}
+
+// repeated int32 public_dependency = 10;
+inline int FileDescriptorProto::_internal_public_dependency_size() const {
+ return _impl_.public_dependency_.size();
+}
+inline int FileDescriptorProto::public_dependency_size() const {
+ return _internal_public_dependency_size();
+}
+inline void FileDescriptorProto::clear_public_dependency() {
+ _impl_.public_dependency_.Clear();
+}
+inline int32_t FileDescriptorProto::_internal_public_dependency(int index) const {
+ return _impl_.public_dependency_.Get(index);
+}
+inline int32_t 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, int32_t value) {
+ _impl_.public_dependency_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.public_dependency)
+}
+inline void FileDescriptorProto::_internal_add_public_dependency(int32_t value) {
+ _impl_.public_dependency_.Add(value);
+}
+inline void FileDescriptorProto::add_public_dependency(int32_t value) {
+ _internal_add_public_dependency(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.public_dependency)
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+FileDescriptorProto::_internal_public_dependency() const {
+ return _impl_.public_dependency_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+FileDescriptorProto::public_dependency() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.public_dependency)
+ return _internal_public_dependency();
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+FileDescriptorProto::_internal_mutable_public_dependency() {
+ return &_impl_.public_dependency_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+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 _impl_.weak_dependency_.size();
+}
+inline int FileDescriptorProto::weak_dependency_size() const {
+ return _internal_weak_dependency_size();
+}
+inline void FileDescriptorProto::clear_weak_dependency() {
+ _impl_.weak_dependency_.Clear();
+}
+inline int32_t FileDescriptorProto::_internal_weak_dependency(int index) const {
+ return _impl_.weak_dependency_.Get(index);
+}
+inline int32_t 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, int32_t value) {
+ _impl_.weak_dependency_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.weak_dependency)
+}
+inline void FileDescriptorProto::_internal_add_weak_dependency(int32_t value) {
+ _impl_.weak_dependency_.Add(value);
+}
+inline void FileDescriptorProto::add_weak_dependency(int32_t value) {
+ _internal_add_weak_dependency(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.weak_dependency)
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+FileDescriptorProto::_internal_weak_dependency() const {
+ return _impl_.weak_dependency_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+FileDescriptorProto::weak_dependency() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.weak_dependency)
+ return _internal_weak_dependency();
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+FileDescriptorProto::_internal_mutable_weak_dependency() {
+ return &_impl_.weak_dependency_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+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 _impl_.message_type_.size();
+}
+inline int FileDescriptorProto::message_type_size() const {
+ return _internal_message_type_size();
+}
+inline void FileDescriptorProto::clear_message_type() {
+ _impl_.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 _impl_.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 &_impl_.message_type_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& FileDescriptorProto::_internal_message_type(int index) const {
+ return _impl_.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 _impl_.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 _impl_.message_type_;
+}
+
+// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+inline int FileDescriptorProto::_internal_enum_type_size() const {
+ return _impl_.enum_type_.size();
+}
+inline int FileDescriptorProto::enum_type_size() const {
+ return _internal_enum_type_size();
+}
+inline void FileDescriptorProto::clear_enum_type() {
+ _impl_.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 _impl_.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 &_impl_.enum_type_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& FileDescriptorProto::_internal_enum_type(int index) const {
+ return _impl_.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 _impl_.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 _impl_.enum_type_;
+}
+
+// repeated .google.protobuf.ServiceDescriptorProto service = 6;
+inline int FileDescriptorProto::_internal_service_size() const {
+ return _impl_.service_.size();
+}
+inline int FileDescriptorProto::service_size() const {
+ return _internal_service_size();
+}
+inline void FileDescriptorProto::clear_service() {
+ _impl_.service_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.service)
+ return _impl_.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 &_impl_.service_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto& FileDescriptorProto::_internal_service(int index) const {
+ return _impl_.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 _impl_.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 _impl_.service_;
+}
+
+// repeated .google.protobuf.FieldDescriptorProto extension = 7;
+inline int FileDescriptorProto::_internal_extension_size() const {
+ return _impl_.extension_.size();
+}
+inline int FileDescriptorProto::extension_size() const {
+ return _internal_extension_size();
+}
+inline void FileDescriptorProto::clear_extension() {
+ _impl_.extension_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.extension)
+ return _impl_.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 &_impl_.extension_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& FileDescriptorProto::_internal_extension(int index) const {
+ return _impl_.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 _impl_.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 _impl_.extension_;
+}
+
+// optional .google.protobuf.FileOptions options = 8;
+inline bool FileDescriptorProto::_internal_has_options() const {
+ bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
+ PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
+ return value;
+}
+inline bool FileDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void FileDescriptorProto::clear_options() {
+ if (_impl_.options_ != nullptr) _impl_.options_->Clear();
+ _impl_._has_bits_[0] &= ~0x00000008u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FileOptions& FileDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::FileOptions* p = _impl_.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*>(_impl_.options_);
+ }
+ _impl_.options_ = options;
+ if (options) {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000008u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::release_options() {
+ _impl_._has_bits_[0] &= ~0x00000008u;
+ ::PROTOBUF_NAMESPACE_ID::FileOptions* temp = _impl_.options_;
+ _impl_.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)
+ _impl_._has_bits_[0] &= ~0x00000008u;
+ ::PROTOBUF_NAMESPACE_ID::FileOptions* temp = _impl_.options_;
+ _impl_.options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::_internal_mutable_options() {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ if (_impl_.options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FileOptions>(GetArenaForAllocation());
+ _impl_.options_ = p;
+ }
+ return _impl_.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 _impl_.options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _impl_._has_bits_[0] |= 0x00000008u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000008u;
+ }
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000010u) != 0;
+ PROTOBUF_ASSUME(!value || _impl_.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 (_impl_.source_code_info_ != nullptr) _impl_.source_code_info_->Clear();
+ _impl_._has_bits_[0] &= ~0x00000010u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::_internal_source_code_info() const {
+ const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* p = _impl_.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*>(_impl_.source_code_info_);
+ }
+ _impl_.source_code_info_ = source_code_info;
+ if (source_code_info) {
+ _impl_._has_bits_[0] |= 0x00000010u;
+ } else {
+ _impl_._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() {
+ _impl_._has_bits_[0] &= ~0x00000010u;
+ ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* temp = _impl_.source_code_info_;
+ _impl_.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)
+ _impl_._has_bits_[0] &= ~0x00000010u;
+ ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* temp = _impl_.source_code_info_;
+ _impl_.source_code_info_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::_internal_mutable_source_code_info() {
+ _impl_._has_bits_[0] |= 0x00000010u;
+ if (_impl_.source_code_info_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceCodeInfo>(GetArenaForAllocation());
+ _impl_.source_code_info_ = p;
+ }
+ return _impl_.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 _impl_.source_code_info_;
+ }
+ if (source_code_info) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(source_code_info);
+ if (message_arena != submessage_arena) {
+ source_code_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, source_code_info, submessage_arena);
+ }
+ _impl_._has_bits_[0] |= 0x00000010u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000010u;
+ }
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool FileDescriptorProto::has_syntax() const {
+ return _internal_has_syntax();
+}
+inline void FileDescriptorProto::clear_syntax() {
+ _impl_.syntax_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000004u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.syntax_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.syntax)
+}
+inline std::string* FileDescriptorProto::mutable_syntax() {
+ std::string* _s = _internal_mutable_syntax();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.syntax)
+ return _s;
+}
+inline const std::string& FileDescriptorProto::_internal_syntax() const {
+ return _impl_.syntax_.Get();
+}
+inline void FileDescriptorProto::_internal_set_syntax(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.syntax_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FileDescriptorProto::_internal_mutable_syntax() {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ return _impl_.syntax_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FileDescriptorProto::release_syntax() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.syntax)
+ if (!_internal_has_syntax()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000004u;
+ auto* p = _impl_.syntax_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.syntax_.IsDefault()) {
+ _impl_.syntax_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileDescriptorProto::set_allocated_syntax(std::string* syntax) {
+ if (syntax != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000004u;
+ }
+ _impl_.syntax_.SetAllocated(syntax, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.syntax_.IsDefault()) {
+ _impl_.syntax_.Set("", 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 = (_impl_._has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool DescriptorProto_ExtensionRange::has_start() const {
+ return _internal_has_start();
+}
+inline void DescriptorProto_ExtensionRange::clear_start() {
+ _impl_.start_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline int32_t DescriptorProto_ExtensionRange::_internal_start() const {
+ return _impl_.start_;
+}
+inline int32_t DescriptorProto_ExtensionRange::start() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.start)
+ return _internal_start();
+}
+inline void DescriptorProto_ExtensionRange::_internal_set_start(int32_t value) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.start_ = value;
+}
+inline void DescriptorProto_ExtensionRange::set_start(int32_t 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 = (_impl_._has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool DescriptorProto_ExtensionRange::has_end() const {
+ return _internal_has_end();
+}
+inline void DescriptorProto_ExtensionRange::clear_end() {
+ _impl_.end_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000004u;
+}
+inline int32_t DescriptorProto_ExtensionRange::_internal_end() const {
+ return _impl_.end_;
+}
+inline int32_t DescriptorProto_ExtensionRange::end() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.end)
+ return _internal_end();
+}
+inline void DescriptorProto_ExtensionRange::_internal_set_end(int32_t value) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.end_ = value;
+}
+inline void DescriptorProto_ExtensionRange::set_end(int32_t 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 = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
+ return value;
+}
+inline bool DescriptorProto_ExtensionRange::has_options() const {
+ return _internal_has_options();
+}
+inline void DescriptorProto_ExtensionRange::clear_options() {
+ if (_impl_.options_ != nullptr) _impl_.options_->Clear();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* p = _impl_.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*>(_impl_.options_);
+ }
+ _impl_.options_ = options;
+ if (options) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._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() {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* temp = _impl_.options_;
+ _impl_.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)
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* temp = _impl_.options_;
+ _impl_.options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::_internal_mutable_options() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ if (_impl_.options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions>(GetArenaForAllocation());
+ _impl_.options_ = p;
+ }
+ return _impl_.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 _impl_.options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool DescriptorProto_ReservedRange::has_start() const {
+ return _internal_has_start();
+}
+inline void DescriptorProto_ReservedRange::clear_start() {
+ _impl_.start_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline int32_t DescriptorProto_ReservedRange::_internal_start() const {
+ return _impl_.start_;
+}
+inline int32_t DescriptorProto_ReservedRange::start() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ReservedRange.start)
+ return _internal_start();
+}
+inline void DescriptorProto_ReservedRange::_internal_set_start(int32_t value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.start_ = value;
+}
+inline void DescriptorProto_ReservedRange::set_start(int32_t 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 = (_impl_._has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool DescriptorProto_ReservedRange::has_end() const {
+ return _internal_has_end();
+}
+inline void DescriptorProto_ReservedRange::clear_end() {
+ _impl_.end_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline int32_t DescriptorProto_ReservedRange::_internal_end() const {
+ return _impl_.end_;
+}
+inline int32_t DescriptorProto_ReservedRange::end() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ReservedRange.end)
+ return _internal_end();
+}
+inline void DescriptorProto_ReservedRange::_internal_set_end(int32_t value) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.end_ = value;
+}
+inline void DescriptorProto_ReservedRange::set_end(int32_t 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 = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool DescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void DescriptorProto::clear_name() {
+ _impl_.name_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.name)
+}
+inline std::string* DescriptorProto::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.name)
+ return _s;
+}
+inline const std::string& DescriptorProto::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void DescriptorProto::_internal_set_name(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* DescriptorProto::_internal_mutable_name() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* DescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ auto* p = _impl_.name_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void DescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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 _impl_.field_.size();
+}
+inline int DescriptorProto::field_size() const {
+ return _internal_field_size();
+}
+inline void DescriptorProto::clear_field() {
+ _impl_.field_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::mutable_field(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.field)
+ return _impl_.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 &_impl_.field_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& DescriptorProto::_internal_field(int index) const {
+ return _impl_.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 _impl_.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 _impl_.field_;
+}
+
+// repeated .google.protobuf.FieldDescriptorProto extension = 6;
+inline int DescriptorProto::_internal_extension_size() const {
+ return _impl_.extension_.size();
+}
+inline int DescriptorProto::extension_size() const {
+ return _internal_extension_size();
+}
+inline void DescriptorProto::clear_extension() {
+ _impl_.extension_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension)
+ return _impl_.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 &_impl_.extension_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& DescriptorProto::_internal_extension(int index) const {
+ return _impl_.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 _impl_.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 _impl_.extension_;
+}
+
+// repeated .google.protobuf.DescriptorProto nested_type = 3;
+inline int DescriptorProto::_internal_nested_type_size() const {
+ return _impl_.nested_type_.size();
+}
+inline int DescriptorProto::nested_type_size() const {
+ return _internal_nested_type_size();
+}
+inline void DescriptorProto::clear_nested_type() {
+ _impl_.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 _impl_.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 &_impl_.nested_type_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& DescriptorProto::_internal_nested_type(int index) const {
+ return _impl_.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 _impl_.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 _impl_.nested_type_;
+}
+
+// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+inline int DescriptorProto::_internal_enum_type_size() const {
+ return _impl_.enum_type_.size();
+}
+inline int DescriptorProto::enum_type_size() const {
+ return _internal_enum_type_size();
+}
+inline void DescriptorProto::clear_enum_type() {
+ _impl_.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 _impl_.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 &_impl_.enum_type_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& DescriptorProto::_internal_enum_type(int index) const {
+ return _impl_.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 _impl_.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 _impl_.enum_type_;
+}
+
+// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+inline int DescriptorProto::_internal_extension_range_size() const {
+ return _impl_.extension_range_.size();
+}
+inline int DescriptorProto::extension_range_size() const {
+ return _internal_extension_range_size();
+}
+inline void DescriptorProto::clear_extension_range() {
+ _impl_.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 _impl_.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 &_impl_.extension_range_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange& DescriptorProto::_internal_extension_range(int index) const {
+ return _impl_.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 _impl_.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 _impl_.extension_range_;
+}
+
+// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+inline int DescriptorProto::_internal_oneof_decl_size() const {
+ return _impl_.oneof_decl_.size();
+}
+inline int DescriptorProto::oneof_decl_size() const {
+ return _internal_oneof_decl_size();
+}
+inline void DescriptorProto::clear_oneof_decl() {
+ _impl_.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 _impl_.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 &_impl_.oneof_decl_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto& DescriptorProto::_internal_oneof_decl(int index) const {
+ return _impl_.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 _impl_.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 _impl_.oneof_decl_;
+}
+
+// optional .google.protobuf.MessageOptions options = 7;
+inline bool DescriptorProto::_internal_has_options() const {
+ bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
+ PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
+ return value;
+}
+inline bool DescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void DescriptorProto::clear_options() {
+ if (_impl_.options_ != nullptr) _impl_.options_->Clear();
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::MessageOptions* p = _impl_.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*>(_impl_.options_);
+ }
+ _impl_.options_ = options;
+ if (options) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::release_options() {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::MessageOptions* temp = _impl_.options_;
+ _impl_.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)
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::MessageOptions* temp = _impl_.options_;
+ _impl_.options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::_internal_mutable_options() {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ if (_impl_.options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MessageOptions>(GetArenaForAllocation());
+ _impl_.options_ = p;
+ }
+ return _impl_.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 _impl_.options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ _impl_.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 _impl_.reserved_range_.size();
+}
+inline int DescriptorProto::reserved_range_size() const {
+ return _internal_reserved_range_size();
+}
+inline void DescriptorProto::clear_reserved_range() {
+ _impl_.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 _impl_.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 &_impl_.reserved_range_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange& DescriptorProto::_internal_reserved_range(int index) const {
+ return _impl_.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 _impl_.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 _impl_.reserved_range_;
+}
+
+// repeated string reserved_name = 10;
+inline int DescriptorProto::_internal_reserved_name_size() const {
+ return _impl_.reserved_name_.size();
+}
+inline int DescriptorProto::reserved_name_size() const {
+ return _internal_reserved_name_size();
+}
+inline void DescriptorProto::clear_reserved_name() {
+ _impl_.reserved_name_.Clear();
+}
+inline std::string* DescriptorProto::add_reserved_name() {
+ std::string* _s = _internal_add_reserved_name();
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.DescriptorProto.reserved_name)
+ return _s;
+}
+inline const std::string& DescriptorProto::_internal_reserved_name(int index) const {
+ return _impl_.reserved_name_.Get(index);
+}
+inline const std::string& DescriptorProto::reserved_name(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_name)
+ return _internal_reserved_name(index);
+}
+inline std::string* DescriptorProto::mutable_reserved_name(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_name)
+ return _impl_.reserved_name_.Mutable(index);
+}
+inline void DescriptorProto::set_reserved_name(int index, const std::string& value) {
+ _impl_.reserved_name_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name)
+}
+inline void DescriptorProto::set_reserved_name(int index, std::string&& value) {
+ _impl_.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);
+ _impl_.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) {
+ _impl_.reserved_name_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.reserved_name)
+}
+inline std::string* DescriptorProto::_internal_add_reserved_name() {
+ return _impl_.reserved_name_.Add();
+}
+inline void DescriptorProto::add_reserved_name(const std::string& value) {
+ _impl_.reserved_name_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name)
+}
+inline void DescriptorProto::add_reserved_name(std::string&& value) {
+ _impl_.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);
+ _impl_.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) {
+ _impl_.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<std::string>&
+DescriptorProto::reserved_name() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_name)
+ return _impl_.reserved_name_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
+DescriptorProto::mutable_reserved_name() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_name)
+ return &_impl_.reserved_name_;
+}
+
+// -------------------------------------------------------------------
+
+// ExtensionRangeOptions
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int ExtensionRangeOptions::_internal_uninterpreted_option_size() const {
+ return _impl_.uninterpreted_option_.size();
+}
+inline int ExtensionRangeOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void ExtensionRangeOptions::clear_uninterpreted_option() {
+ _impl_.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 _impl_.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 &_impl_.uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& ExtensionRangeOptions::_internal_uninterpreted_option(int index) const {
+ return _impl_.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 _impl_.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 _impl_.uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// FieldDescriptorProto
+
+// optional string name = 1;
+inline bool FieldDescriptorProto::_internal_has_name() const {
+ bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void FieldDescriptorProto::clear_name() {
+ _impl_.name_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.name)
+}
+inline std::string* FieldDescriptorProto::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.name)
+ return _s;
+}
+inline const std::string& FieldDescriptorProto::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void FieldDescriptorProto::_internal_set_name(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::_internal_mutable_name() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ auto* p = _impl_.name_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FieldDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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 = (_impl_._has_bits_[0] & 0x00000040u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_number() const {
+ return _internal_has_number();
+}
+inline void FieldDescriptorProto::clear_number() {
+ _impl_.number_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000040u;
+}
+inline int32_t FieldDescriptorProto::_internal_number() const {
+ return _impl_.number_;
+}
+inline int32_t FieldDescriptorProto::number() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.number)
+ return _internal_number();
+}
+inline void FieldDescriptorProto::_internal_set_number(int32_t value) {
+ _impl_._has_bits_[0] |= 0x00000040u;
+ _impl_.number_ = value;
+}
+inline void FieldDescriptorProto::set_number(int32_t 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 = (_impl_._has_bits_[0] & 0x00000200u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_label() const {
+ return _internal_has_label();
+}
+inline void FieldDescriptorProto::clear_label() {
+ _impl_.label_ = 1;
+ _impl_._has_bits_[0] &= ~0x00000200u;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label FieldDescriptorProto::_internal_label() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label >(_impl_.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));
+ _impl_._has_bits_[0] |= 0x00000200u;
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000400u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_type() const {
+ return _internal_has_type();
+}
+inline void FieldDescriptorProto::clear_type() {
+ _impl_.type_ = 1;
+ _impl_._has_bits_[0] &= ~0x00000400u;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type FieldDescriptorProto::_internal_type() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type >(_impl_.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));
+ _impl_._has_bits_[0] |= 0x00000400u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.type_name_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000004u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.type_name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type_name)
+}
+inline std::string* FieldDescriptorProto::mutable_type_name() {
+ std::string* _s = _internal_mutable_type_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.type_name)
+ return _s;
+}
+inline const std::string& FieldDescriptorProto::_internal_type_name() const {
+ return _impl_.type_name_.Get();
+}
+inline void FieldDescriptorProto::_internal_set_type_name(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.type_name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::_internal_mutable_type_name() {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ return _impl_.type_name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::release_type_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.type_name)
+ if (!_internal_has_type_name()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000004u;
+ auto* p = _impl_.type_name_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.type_name_.IsDefault()) {
+ _impl_.type_name_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FieldDescriptorProto::set_allocated_type_name(std::string* type_name) {
+ if (type_name != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000004u;
+ }
+ _impl_.type_name_.SetAllocated(type_name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.type_name_.IsDefault()) {
+ _impl_.type_name_.Set("", 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 = (_impl_._has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_extendee() const {
+ return _internal_has_extendee();
+}
+inline void FieldDescriptorProto::clear_extendee() {
+ _impl_.extendee_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.extendee_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.extendee)
+}
+inline std::string* FieldDescriptorProto::mutable_extendee() {
+ std::string* _s = _internal_mutable_extendee();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.extendee)
+ return _s;
+}
+inline const std::string& FieldDescriptorProto::_internal_extendee() const {
+ return _impl_.extendee_.Get();
+}
+inline void FieldDescriptorProto::_internal_set_extendee(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.extendee_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::_internal_mutable_extendee() {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ return _impl_.extendee_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::release_extendee() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.extendee)
+ if (!_internal_has_extendee()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ auto* p = _impl_.extendee_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.extendee_.IsDefault()) {
+ _impl_.extendee_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FieldDescriptorProto::set_allocated_extendee(std::string* extendee) {
+ if (extendee != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ _impl_.extendee_.SetAllocated(extendee, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.extendee_.IsDefault()) {
+ _impl_.extendee_.Set("", 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 = (_impl_._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() {
+ _impl_.default_value_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000008u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ _impl_.default_value_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.default_value)
+}
+inline std::string* FieldDescriptorProto::mutable_default_value() {
+ std::string* _s = _internal_mutable_default_value();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.default_value)
+ return _s;
+}
+inline const std::string& FieldDescriptorProto::_internal_default_value() const {
+ return _impl_.default_value_.Get();
+}
+inline void FieldDescriptorProto::_internal_set_default_value(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ _impl_.default_value_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::_internal_mutable_default_value() {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ return _impl_.default_value_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::release_default_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.default_value)
+ if (!_internal_has_default_value()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000008u;
+ auto* p = _impl_.default_value_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.default_value_.IsDefault()) {
+ _impl_.default_value_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FieldDescriptorProto::set_allocated_default_value(std::string* default_value) {
+ if (default_value != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000008u;
+ }
+ _impl_.default_value_.SetAllocated(default_value, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.default_value_.IsDefault()) {
+ _impl_.default_value_.Set("", 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 = (_impl_._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() {
+ _impl_.oneof_index_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000080u;
+}
+inline int32_t FieldDescriptorProto::_internal_oneof_index() const {
+ return _impl_.oneof_index_;
+}
+inline int32_t 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(int32_t value) {
+ _impl_._has_bits_[0] |= 0x00000080u;
+ _impl_.oneof_index_ = value;
+}
+inline void FieldDescriptorProto::set_oneof_index(int32_t 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 = (_impl_._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() {
+ _impl_.json_name_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000010u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000010u;
+ _impl_.json_name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.json_name)
+}
+inline std::string* FieldDescriptorProto::mutable_json_name() {
+ std::string* _s = _internal_mutable_json_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.json_name)
+ return _s;
+}
+inline const std::string& FieldDescriptorProto::_internal_json_name() const {
+ return _impl_.json_name_.Get();
+}
+inline void FieldDescriptorProto::_internal_set_json_name(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000010u;
+ _impl_.json_name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::_internal_mutable_json_name() {
+ _impl_._has_bits_[0] |= 0x00000010u;
+ return _impl_.json_name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::release_json_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.json_name)
+ if (!_internal_has_json_name()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000010u;
+ auto* p = _impl_.json_name_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.json_name_.IsDefault()) {
+ _impl_.json_name_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FieldDescriptorProto::set_allocated_json_name(std::string* json_name) {
+ if (json_name != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000010u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000010u;
+ }
+ _impl_.json_name_.SetAllocated(json_name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.json_name_.IsDefault()) {
+ _impl_.json_name_.Set("", 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 = (_impl_._has_bits_[0] & 0x00000020u) != 0;
+ PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
+ return value;
+}
+inline bool FieldDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void FieldDescriptorProto::clear_options() {
+ if (_impl_.options_ != nullptr) _impl_.options_->Clear();
+ _impl_._has_bits_[0] &= ~0x00000020u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::FieldOptions* p = _impl_.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*>(_impl_.options_);
+ }
+ _impl_.options_ = options;
+ if (options) {
+ _impl_._has_bits_[0] |= 0x00000020u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000020u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::release_options() {
+ _impl_._has_bits_[0] &= ~0x00000020u;
+ ::PROTOBUF_NAMESPACE_ID::FieldOptions* temp = _impl_.options_;
+ _impl_.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)
+ _impl_._has_bits_[0] &= ~0x00000020u;
+ ::PROTOBUF_NAMESPACE_ID::FieldOptions* temp = _impl_.options_;
+ _impl_.options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::_internal_mutable_options() {
+ _impl_._has_bits_[0] |= 0x00000020u;
+ if (_impl_.options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FieldOptions>(GetArenaForAllocation());
+ _impl_.options_ = p;
+ }
+ return _impl_.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 _impl_.options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _impl_._has_bits_[0] |= 0x00000020u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000020u;
+ }
+ _impl_.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 = (_impl_._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() {
+ _impl_.proto3_optional_ = false;
+ _impl_._has_bits_[0] &= ~0x00000100u;
+}
+inline bool FieldDescriptorProto::_internal_proto3_optional() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000100u;
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool OneofDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void OneofDescriptorProto::clear_name() {
+ _impl_.name_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.OneofDescriptorProto.name)
+}
+inline std::string* OneofDescriptorProto::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.name)
+ return _s;
+}
+inline const std::string& OneofDescriptorProto::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void OneofDescriptorProto::_internal_set_name(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* OneofDescriptorProto::_internal_mutable_name() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* OneofDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ auto* p = _impl_.name_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void OneofDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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 = (_impl_._has_bits_[0] & 0x00000002u) != 0;
+ PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
+ return value;
+}
+inline bool OneofDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void OneofDescriptorProto::clear_options() {
+ if (_impl_.options_ != nullptr) _impl_.options_->Clear();
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::OneofOptions* p = _impl_.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*>(_impl_.options_);
+ }
+ _impl_.options_ = options;
+ if (options) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.OneofDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::release_options() {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::OneofOptions* temp = _impl_.options_;
+ _impl_.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)
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::OneofOptions* temp = _impl_.options_;
+ _impl_.options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::_internal_mutable_options() {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ if (_impl_.options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::OneofOptions>(GetArenaForAllocation());
+ _impl_.options_ = p;
+ }
+ return _impl_.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 _impl_.options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool EnumDescriptorProto_EnumReservedRange::has_start() const {
+ return _internal_has_start();
+}
+inline void EnumDescriptorProto_EnumReservedRange::clear_start() {
+ _impl_.start_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline int32_t EnumDescriptorProto_EnumReservedRange::_internal_start() const {
+ return _impl_.start_;
+}
+inline int32_t EnumDescriptorProto_EnumReservedRange::start() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.EnumReservedRange.start)
+ return _internal_start();
+}
+inline void EnumDescriptorProto_EnumReservedRange::_internal_set_start(int32_t value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.start_ = value;
+}
+inline void EnumDescriptorProto_EnumReservedRange::set_start(int32_t 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 = (_impl_._has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool EnumDescriptorProto_EnumReservedRange::has_end() const {
+ return _internal_has_end();
+}
+inline void EnumDescriptorProto_EnumReservedRange::clear_end() {
+ _impl_.end_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline int32_t EnumDescriptorProto_EnumReservedRange::_internal_end() const {
+ return _impl_.end_;
+}
+inline int32_t EnumDescriptorProto_EnumReservedRange::end() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.EnumReservedRange.end)
+ return _internal_end();
+}
+inline void EnumDescriptorProto_EnumReservedRange::_internal_set_end(int32_t value) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.end_ = value;
+}
+inline void EnumDescriptorProto_EnumReservedRange::set_end(int32_t 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 = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool EnumDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void EnumDescriptorProto::clear_name() {
+ _impl_.name_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.name)
+}
+inline std::string* EnumDescriptorProto::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.name)
+ return _s;
+}
+inline const std::string& EnumDescriptorProto::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void EnumDescriptorProto::_internal_set_name(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* EnumDescriptorProto::_internal_mutable_name() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* EnumDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ auto* p = _impl_.name_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void EnumDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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 _impl_.value_.size();
+}
+inline int EnumDescriptorProto::value_size() const {
+ return _internal_value_size();
+}
+inline void EnumDescriptorProto::clear_value() {
+ _impl_.value_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.value)
+ return _impl_.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 &_impl_.value_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto& EnumDescriptorProto::_internal_value(int index) const {
+ return _impl_.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 _impl_.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 _impl_.value_;
+}
+
+// optional .google.protobuf.EnumOptions options = 3;
+inline bool EnumDescriptorProto::_internal_has_options() const {
+ bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
+ PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
+ return value;
+}
+inline bool EnumDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void EnumDescriptorProto::clear_options() {
+ if (_impl_.options_ != nullptr) _impl_.options_->Clear();
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::EnumOptions* p = _impl_.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*>(_impl_.options_);
+ }
+ _impl_.options_ = options;
+ if (options) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::release_options() {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::EnumOptions* temp = _impl_.options_;
+ _impl_.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)
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::EnumOptions* temp = _impl_.options_;
+ _impl_.options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::_internal_mutable_options() {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ if (_impl_.options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumOptions>(GetArenaForAllocation());
+ _impl_.options_ = p;
+ }
+ return _impl_.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 _impl_.options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ _impl_.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 _impl_.reserved_range_.size();
+}
+inline int EnumDescriptorProto::reserved_range_size() const {
+ return _internal_reserved_range_size();
+}
+inline void EnumDescriptorProto::clear_reserved_range() {
+ _impl_.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 _impl_.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 &_impl_.reserved_range_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange& EnumDescriptorProto::_internal_reserved_range(int index) const {
+ return _impl_.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 _impl_.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 _impl_.reserved_range_;
+}
+
+// repeated string reserved_name = 5;
+inline int EnumDescriptorProto::_internal_reserved_name_size() const {
+ return _impl_.reserved_name_.size();
+}
+inline int EnumDescriptorProto::reserved_name_size() const {
+ return _internal_reserved_name_size();
+}
+inline void EnumDescriptorProto::clear_reserved_name() {
+ _impl_.reserved_name_.Clear();
+}
+inline std::string* EnumDescriptorProto::add_reserved_name() {
+ std::string* _s = _internal_add_reserved_name();
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.EnumDescriptorProto.reserved_name)
+ return _s;
+}
+inline const std::string& EnumDescriptorProto::_internal_reserved_name(int index) const {
+ return _impl_.reserved_name_.Get(index);
+}
+inline const std::string& EnumDescriptorProto::reserved_name(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.reserved_name)
+ return _internal_reserved_name(index);
+}
+inline std::string* EnumDescriptorProto::mutable_reserved_name(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.reserved_name)
+ return _impl_.reserved_name_.Mutable(index);
+}
+inline void EnumDescriptorProto::set_reserved_name(int index, const std::string& value) {
+ _impl_.reserved_name_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.reserved_name)
+}
+inline void EnumDescriptorProto::set_reserved_name(int index, std::string&& value) {
+ _impl_.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);
+ _impl_.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) {
+ _impl_.reserved_name_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumDescriptorProto.reserved_name)
+}
+inline std::string* EnumDescriptorProto::_internal_add_reserved_name() {
+ return _impl_.reserved_name_.Add();
+}
+inline void EnumDescriptorProto::add_reserved_name(const std::string& value) {
+ _impl_.reserved_name_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.reserved_name)
+}
+inline void EnumDescriptorProto::add_reserved_name(std::string&& value) {
+ _impl_.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);
+ _impl_.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) {
+ _impl_.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<std::string>&
+EnumDescriptorProto::reserved_name() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.reserved_name)
+ return _impl_.reserved_name_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
+EnumDescriptorProto::mutable_reserved_name() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.reserved_name)
+ return &_impl_.reserved_name_;
+}
+
+// -------------------------------------------------------------------
+
+// EnumValueDescriptorProto
+
+// optional string name = 1;
+inline bool EnumValueDescriptorProto::_internal_has_name() const {
+ bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool EnumValueDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void EnumValueDescriptorProto::clear_name() {
+ _impl_.name_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.name)
+}
+inline std::string* EnumValueDescriptorProto::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.name)
+ return _s;
+}
+inline const std::string& EnumValueDescriptorProto::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void EnumValueDescriptorProto::_internal_set_name(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* EnumValueDescriptorProto::_internal_mutable_name() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* EnumValueDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ auto* p = _impl_.name_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void EnumValueDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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 = (_impl_._has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool EnumValueDescriptorProto::has_number() const {
+ return _internal_has_number();
+}
+inline void EnumValueDescriptorProto::clear_number() {
+ _impl_.number_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000004u;
+}
+inline int32_t EnumValueDescriptorProto::_internal_number() const {
+ return _impl_.number_;
+}
+inline int32_t EnumValueDescriptorProto::number() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.number)
+ return _internal_number();
+}
+inline void EnumValueDescriptorProto::_internal_set_number(int32_t value) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.number_ = value;
+}
+inline void EnumValueDescriptorProto::set_number(int32_t 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 = (_impl_._has_bits_[0] & 0x00000002u) != 0;
+ PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
+ return value;
+}
+inline bool EnumValueDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void EnumValueDescriptorProto::clear_options() {
+ if (_impl_.options_ != nullptr) _impl_.options_->Clear();
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* p = _impl_.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*>(_impl_.options_);
+ }
+ _impl_.options_ = options;
+ if (options) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::release_options() {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* temp = _impl_.options_;
+ _impl_.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)
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* temp = _impl_.options_;
+ _impl_.options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::_internal_mutable_options() {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ if (_impl_.options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumValueOptions>(GetArenaForAllocation());
+ _impl_.options_ = p;
+ }
+ return _impl_.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 _impl_.options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool ServiceDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void ServiceDescriptorProto::clear_name() {
+ _impl_.name_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.ServiceDescriptorProto.name)
+}
+inline std::string* ServiceDescriptorProto::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.name)
+ return _s;
+}
+inline const std::string& ServiceDescriptorProto::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void ServiceDescriptorProto::_internal_set_name(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* ServiceDescriptorProto::_internal_mutable_name() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* ServiceDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ auto* p = _impl_.name_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void ServiceDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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 _impl_.method_.size();
+}
+inline int ServiceDescriptorProto::method_size() const {
+ return _internal_method_size();
+}
+inline void ServiceDescriptorProto::clear_method() {
+ _impl_.method_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.method)
+ return _impl_.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 &_impl_.method_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto& ServiceDescriptorProto::_internal_method(int index) const {
+ return _impl_.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 _impl_.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 _impl_.method_;
+}
+
+// optional .google.protobuf.ServiceOptions options = 3;
+inline bool ServiceDescriptorProto::_internal_has_options() const {
+ bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
+ PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
+ return value;
+}
+inline bool ServiceDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void ServiceDescriptorProto::clear_options() {
+ if (_impl_.options_ != nullptr) _impl_.options_->Clear();
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::ServiceOptions* p = _impl_.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*>(_impl_.options_);
+ }
+ _impl_.options_ = options;
+ if (options) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.ServiceDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::release_options() {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::ServiceOptions* temp = _impl_.options_;
+ _impl_.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)
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::ServiceOptions* temp = _impl_.options_;
+ _impl_.options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::_internal_mutable_options() {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ if (_impl_.options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ServiceOptions>(GetArenaForAllocation());
+ _impl_.options_ = p;
+ }
+ return _impl_.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 _impl_.options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool MethodDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void MethodDescriptorProto::clear_name() {
+ _impl_.name_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.name)
+}
+inline std::string* MethodDescriptorProto::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.name)
+ return _s;
+}
+inline const std::string& MethodDescriptorProto::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void MethodDescriptorProto::_internal_set_name(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* MethodDescriptorProto::_internal_mutable_name() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* MethodDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ auto* p = _impl_.name_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void MethodDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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 = (_impl_._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() {
+ _impl_.input_type_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.input_type_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.input_type)
+}
+inline std::string* MethodDescriptorProto::mutable_input_type() {
+ std::string* _s = _internal_mutable_input_type();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.input_type)
+ return _s;
+}
+inline const std::string& MethodDescriptorProto::_internal_input_type() const {
+ return _impl_.input_type_.Get();
+}
+inline void MethodDescriptorProto::_internal_set_input_type(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.input_type_.Set(value, GetArenaForAllocation());
+}
+inline std::string* MethodDescriptorProto::_internal_mutable_input_type() {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ return _impl_.input_type_.Mutable(GetArenaForAllocation());
+}
+inline std::string* MethodDescriptorProto::release_input_type() {
+ // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.input_type)
+ if (!_internal_has_input_type()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ auto* p = _impl_.input_type_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.input_type_.IsDefault()) {
+ _impl_.input_type_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void MethodDescriptorProto::set_allocated_input_type(std::string* input_type) {
+ if (input_type != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ _impl_.input_type_.SetAllocated(input_type, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.input_type_.IsDefault()) {
+ _impl_.input_type_.Set("", 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 = (_impl_._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() {
+ _impl_.output_type_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000004u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.output_type_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.output_type)
+}
+inline std::string* MethodDescriptorProto::mutable_output_type() {
+ std::string* _s = _internal_mutable_output_type();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.output_type)
+ return _s;
+}
+inline const std::string& MethodDescriptorProto::_internal_output_type() const {
+ return _impl_.output_type_.Get();
+}
+inline void MethodDescriptorProto::_internal_set_output_type(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.output_type_.Set(value, GetArenaForAllocation());
+}
+inline std::string* MethodDescriptorProto::_internal_mutable_output_type() {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ return _impl_.output_type_.Mutable(GetArenaForAllocation());
+}
+inline std::string* MethodDescriptorProto::release_output_type() {
+ // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.output_type)
+ if (!_internal_has_output_type()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000004u;
+ auto* p = _impl_.output_type_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.output_type_.IsDefault()) {
+ _impl_.output_type_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void MethodDescriptorProto::set_allocated_output_type(std::string* output_type) {
+ if (output_type != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000004u;
+ }
+ _impl_.output_type_.SetAllocated(output_type, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.output_type_.IsDefault()) {
+ _impl_.output_type_.Set("", 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 = (_impl_._has_bits_[0] & 0x00000008u) != 0;
+ PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
+ return value;
+}
+inline bool MethodDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void MethodDescriptorProto::clear_options() {
+ if (_impl_.options_ != nullptr) _impl_.options_->Clear();
+ _impl_._has_bits_[0] &= ~0x00000008u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::MethodOptions* p = _impl_.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*>(_impl_.options_);
+ }
+ _impl_.options_ = options;
+ if (options) {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000008u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MethodDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::release_options() {
+ _impl_._has_bits_[0] &= ~0x00000008u;
+ ::PROTOBUF_NAMESPACE_ID::MethodOptions* temp = _impl_.options_;
+ _impl_.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)
+ _impl_._has_bits_[0] &= ~0x00000008u;
+ ::PROTOBUF_NAMESPACE_ID::MethodOptions* temp = _impl_.options_;
+ _impl_.options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::_internal_mutable_options() {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ if (_impl_.options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MethodOptions>(GetArenaForAllocation());
+ _impl_.options_ = p;
+ }
+ return _impl_.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 _impl_.options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _impl_._has_bits_[0] |= 0x00000008u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000008u;
+ }
+ _impl_.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 = (_impl_._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() {
+ _impl_.client_streaming_ = false;
+ _impl_._has_bits_[0] &= ~0x00000010u;
+}
+inline bool MethodDescriptorProto::_internal_client_streaming() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000010u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.server_streaming_ = false;
+ _impl_._has_bits_[0] &= ~0x00000020u;
+}
+inline bool MethodDescriptorProto::_internal_server_streaming() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000020u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.java_package_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.java_package_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_package)
+}
+inline std::string* FileOptions::mutable_java_package() {
+ std::string* _s = _internal_mutable_java_package();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_package)
+ return _s;
+}
+inline const std::string& FileOptions::_internal_java_package() const {
+ return _impl_.java_package_.Get();
+}
+inline void FileOptions::_internal_set_java_package(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.java_package_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_java_package() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ return _impl_.java_package_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FileOptions::release_java_package() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_package)
+ if (!_internal_has_java_package()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ auto* p = _impl_.java_package_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.java_package_.IsDefault()) {
+ _impl_.java_package_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_java_package(std::string* java_package) {
+ if (java_package != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.java_package_.SetAllocated(java_package, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.java_package_.IsDefault()) {
+ _impl_.java_package_.Set("", 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 = (_impl_._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() {
+ _impl_.java_outer_classname_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.java_outer_classname_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_outer_classname)
+}
+inline std::string* FileOptions::mutable_java_outer_classname() {
+ std::string* _s = _internal_mutable_java_outer_classname();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_outer_classname)
+ return _s;
+}
+inline const std::string& FileOptions::_internal_java_outer_classname() const {
+ return _impl_.java_outer_classname_.Get();
+}
+inline void FileOptions::_internal_set_java_outer_classname(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.java_outer_classname_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_java_outer_classname() {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ return _impl_.java_outer_classname_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FileOptions::release_java_outer_classname() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_outer_classname)
+ if (!_internal_has_java_outer_classname()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ auto* p = _impl_.java_outer_classname_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.java_outer_classname_.IsDefault()) {
+ _impl_.java_outer_classname_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_java_outer_classname(std::string* java_outer_classname) {
+ if (java_outer_classname != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ _impl_.java_outer_classname_.SetAllocated(java_outer_classname, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.java_outer_classname_.IsDefault()) {
+ _impl_.java_outer_classname_.Set("", 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 = (_impl_._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() {
+ _impl_.java_multiple_files_ = false;
+ _impl_._has_bits_[0] &= ~0x00000400u;
+}
+inline bool FileOptions::_internal_java_multiple_files() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000400u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.java_generate_equals_and_hash_ = false;
+ _impl_._has_bits_[0] &= ~0x00000800u;
+}
+inline bool FileOptions::_internal_java_generate_equals_and_hash() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000800u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.java_string_check_utf8_ = false;
+ _impl_._has_bits_[0] &= ~0x00001000u;
+}
+inline bool FileOptions::_internal_java_string_check_utf8() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00001000u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.optimize_for_ = 1;
+ _impl_._has_bits_[0] &= ~0x00040000u;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode FileOptions::_internal_optimize_for() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode >(_impl_.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));
+ _impl_._has_bits_[0] |= 0x00040000u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.go_package_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000004u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.go_package_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.go_package)
+}
+inline std::string* FileOptions::mutable_go_package() {
+ std::string* _s = _internal_mutable_go_package();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.go_package)
+ return _s;
+}
+inline const std::string& FileOptions::_internal_go_package() const {
+ return _impl_.go_package_.Get();
+}
+inline void FileOptions::_internal_set_go_package(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.go_package_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_go_package() {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ return _impl_.go_package_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FileOptions::release_go_package() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.go_package)
+ if (!_internal_has_go_package()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000004u;
+ auto* p = _impl_.go_package_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.go_package_.IsDefault()) {
+ _impl_.go_package_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_go_package(std::string* go_package) {
+ if (go_package != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000004u;
+ }
+ _impl_.go_package_.SetAllocated(go_package, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.go_package_.IsDefault()) {
+ _impl_.go_package_.Set("", 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 = (_impl_._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() {
+ _impl_.cc_generic_services_ = false;
+ _impl_._has_bits_[0] &= ~0x00002000u;
+}
+inline bool FileOptions::_internal_cc_generic_services() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00002000u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.java_generic_services_ = false;
+ _impl_._has_bits_[0] &= ~0x00004000u;
+}
+inline bool FileOptions::_internal_java_generic_services() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00004000u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.py_generic_services_ = false;
+ _impl_._has_bits_[0] &= ~0x00008000u;
+}
+inline bool FileOptions::_internal_py_generic_services() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00008000u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.php_generic_services_ = false;
+ _impl_._has_bits_[0] &= ~0x00010000u;
+}
+inline bool FileOptions::_internal_php_generic_services() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00010000u;
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00020000u) != 0;
+ return value;
+}
+inline bool FileOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void FileOptions::clear_deprecated() {
+ _impl_.deprecated_ = false;
+ _impl_._has_bits_[0] &= ~0x00020000u;
+}
+inline bool FileOptions::_internal_deprecated() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00020000u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.cc_enable_arenas_ = true;
+ _impl_._has_bits_[0] &= ~0x00080000u;
+}
+inline bool FileOptions::_internal_cc_enable_arenas() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00080000u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.objc_class_prefix_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000008u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ _impl_.objc_class_prefix_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.objc_class_prefix)
+}
+inline std::string* FileOptions::mutable_objc_class_prefix() {
+ std::string* _s = _internal_mutable_objc_class_prefix();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.objc_class_prefix)
+ return _s;
+}
+inline const std::string& FileOptions::_internal_objc_class_prefix() const {
+ return _impl_.objc_class_prefix_.Get();
+}
+inline void FileOptions::_internal_set_objc_class_prefix(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ _impl_.objc_class_prefix_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_objc_class_prefix() {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ return _impl_.objc_class_prefix_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FileOptions::release_objc_class_prefix() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.objc_class_prefix)
+ if (!_internal_has_objc_class_prefix()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000008u;
+ auto* p = _impl_.objc_class_prefix_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.objc_class_prefix_.IsDefault()) {
+ _impl_.objc_class_prefix_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_objc_class_prefix(std::string* objc_class_prefix) {
+ if (objc_class_prefix != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000008u;
+ }
+ _impl_.objc_class_prefix_.SetAllocated(objc_class_prefix, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.objc_class_prefix_.IsDefault()) {
+ _impl_.objc_class_prefix_.Set("", 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 = (_impl_._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() {
+ _impl_.csharp_namespace_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000010u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000010u;
+ _impl_.csharp_namespace_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_namespace)
+}
+inline std::string* FileOptions::mutable_csharp_namespace() {
+ std::string* _s = _internal_mutable_csharp_namespace();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_namespace)
+ return _s;
+}
+inline const std::string& FileOptions::_internal_csharp_namespace() const {
+ return _impl_.csharp_namespace_.Get();
+}
+inline void FileOptions::_internal_set_csharp_namespace(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000010u;
+ _impl_.csharp_namespace_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_csharp_namespace() {
+ _impl_._has_bits_[0] |= 0x00000010u;
+ return _impl_.csharp_namespace_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FileOptions::release_csharp_namespace() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.csharp_namespace)
+ if (!_internal_has_csharp_namespace()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000010u;
+ auto* p = _impl_.csharp_namespace_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.csharp_namespace_.IsDefault()) {
+ _impl_.csharp_namespace_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_csharp_namespace(std::string* csharp_namespace) {
+ if (csharp_namespace != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000010u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000010u;
+ }
+ _impl_.csharp_namespace_.SetAllocated(csharp_namespace, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.csharp_namespace_.IsDefault()) {
+ _impl_.csharp_namespace_.Set("", 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 = (_impl_._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() {
+ _impl_.swift_prefix_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000020u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000020u;
+ _impl_.swift_prefix_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.swift_prefix)
+}
+inline std::string* FileOptions::mutable_swift_prefix() {
+ std::string* _s = _internal_mutable_swift_prefix();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.swift_prefix)
+ return _s;
+}
+inline const std::string& FileOptions::_internal_swift_prefix() const {
+ return _impl_.swift_prefix_.Get();
+}
+inline void FileOptions::_internal_set_swift_prefix(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000020u;
+ _impl_.swift_prefix_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_swift_prefix() {
+ _impl_._has_bits_[0] |= 0x00000020u;
+ return _impl_.swift_prefix_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FileOptions::release_swift_prefix() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.swift_prefix)
+ if (!_internal_has_swift_prefix()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000020u;
+ auto* p = _impl_.swift_prefix_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.swift_prefix_.IsDefault()) {
+ _impl_.swift_prefix_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_swift_prefix(std::string* swift_prefix) {
+ if (swift_prefix != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000020u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000020u;
+ }
+ _impl_.swift_prefix_.SetAllocated(swift_prefix, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.swift_prefix_.IsDefault()) {
+ _impl_.swift_prefix_.Set("", 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 = (_impl_._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() {
+ _impl_.php_class_prefix_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000040u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000040u;
+ _impl_.php_class_prefix_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_class_prefix)
+}
+inline std::string* FileOptions::mutable_php_class_prefix() {
+ std::string* _s = _internal_mutable_php_class_prefix();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_class_prefix)
+ return _s;
+}
+inline const std::string& FileOptions::_internal_php_class_prefix() const {
+ return _impl_.php_class_prefix_.Get();
+}
+inline void FileOptions::_internal_set_php_class_prefix(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000040u;
+ _impl_.php_class_prefix_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_php_class_prefix() {
+ _impl_._has_bits_[0] |= 0x00000040u;
+ return _impl_.php_class_prefix_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FileOptions::release_php_class_prefix() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_class_prefix)
+ if (!_internal_has_php_class_prefix()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000040u;
+ auto* p = _impl_.php_class_prefix_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.php_class_prefix_.IsDefault()) {
+ _impl_.php_class_prefix_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_php_class_prefix(std::string* php_class_prefix) {
+ if (php_class_prefix != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000040u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000040u;
+ }
+ _impl_.php_class_prefix_.SetAllocated(php_class_prefix, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.php_class_prefix_.IsDefault()) {
+ _impl_.php_class_prefix_.Set("", 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 = (_impl_._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() {
+ _impl_.php_namespace_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000080u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000080u;
+ _impl_.php_namespace_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_namespace)
+}
+inline std::string* FileOptions::mutable_php_namespace() {
+ std::string* _s = _internal_mutable_php_namespace();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_namespace)
+ return _s;
+}
+inline const std::string& FileOptions::_internal_php_namespace() const {
+ return _impl_.php_namespace_.Get();
+}
+inline void FileOptions::_internal_set_php_namespace(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000080u;
+ _impl_.php_namespace_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_php_namespace() {
+ _impl_._has_bits_[0] |= 0x00000080u;
+ return _impl_.php_namespace_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FileOptions::release_php_namespace() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_namespace)
+ if (!_internal_has_php_namespace()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000080u;
+ auto* p = _impl_.php_namespace_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.php_namespace_.IsDefault()) {
+ _impl_.php_namespace_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_php_namespace(std::string* php_namespace) {
+ if (php_namespace != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000080u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000080u;
+ }
+ _impl_.php_namespace_.SetAllocated(php_namespace, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.php_namespace_.IsDefault()) {
+ _impl_.php_namespace_.Set("", 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 = (_impl_._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() {
+ _impl_.php_metadata_namespace_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000100u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000100u;
+ _impl_.php_metadata_namespace_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_metadata_namespace)
+}
+inline std::string* FileOptions::mutable_php_metadata_namespace() {
+ std::string* _s = _internal_mutable_php_metadata_namespace();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_metadata_namespace)
+ return _s;
+}
+inline const std::string& FileOptions::_internal_php_metadata_namespace() const {
+ return _impl_.php_metadata_namespace_.Get();
+}
+inline void FileOptions::_internal_set_php_metadata_namespace(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000100u;
+ _impl_.php_metadata_namespace_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_php_metadata_namespace() {
+ _impl_._has_bits_[0] |= 0x00000100u;
+ return _impl_.php_metadata_namespace_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FileOptions::release_php_metadata_namespace() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_metadata_namespace)
+ if (!_internal_has_php_metadata_namespace()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000100u;
+ auto* p = _impl_.php_metadata_namespace_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.php_metadata_namespace_.IsDefault()) {
+ _impl_.php_metadata_namespace_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_php_metadata_namespace(std::string* php_metadata_namespace) {
+ if (php_metadata_namespace != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000100u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000100u;
+ }
+ _impl_.php_metadata_namespace_.SetAllocated(php_metadata_namespace, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.php_metadata_namespace_.IsDefault()) {
+ _impl_.php_metadata_namespace_.Set("", 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 = (_impl_._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() {
+ _impl_.ruby_package_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000200u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000200u;
+ _impl_.ruby_package_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.ruby_package)
+}
+inline std::string* FileOptions::mutable_ruby_package() {
+ std::string* _s = _internal_mutable_ruby_package();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.ruby_package)
+ return _s;
+}
+inline const std::string& FileOptions::_internal_ruby_package() const {
+ return _impl_.ruby_package_.Get();
+}
+inline void FileOptions::_internal_set_ruby_package(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000200u;
+ _impl_.ruby_package_.Set(value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_ruby_package() {
+ _impl_._has_bits_[0] |= 0x00000200u;
+ return _impl_.ruby_package_.Mutable(GetArenaForAllocation());
+}
+inline std::string* FileOptions::release_ruby_package() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.ruby_package)
+ if (!_internal_has_ruby_package()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000200u;
+ auto* p = _impl_.ruby_package_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.ruby_package_.IsDefault()) {
+ _impl_.ruby_package_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_ruby_package(std::string* ruby_package) {
+ if (ruby_package != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000200u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000200u;
+ }
+ _impl_.ruby_package_.SetAllocated(ruby_package, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.ruby_package_.IsDefault()) {
+ _impl_.ruby_package_.Set("", 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 _impl_.uninterpreted_option_.size();
+}
+inline int FileOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void FileOptions::clear_uninterpreted_option() {
+ _impl_.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 _impl_.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 &_impl_.uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& FileOptions::_internal_uninterpreted_option(int index) const {
+ return _impl_.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 _impl_.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 _impl_.uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// MessageOptions
+
+// optional bool message_set_wire_format = 1 [default = false];
+inline bool MessageOptions::_internal_has_message_set_wire_format() const {
+ bool value = (_impl_._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() {
+ _impl_.message_set_wire_format_ = false;
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline bool MessageOptions::_internal_message_set_wire_format() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.no_standard_descriptor_accessor_ = false;
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline bool MessageOptions::_internal_no_standard_descriptor_accessor() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool MessageOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void MessageOptions::clear_deprecated() {
+ _impl_.deprecated_ = false;
+ _impl_._has_bits_[0] &= ~0x00000004u;
+}
+inline bool MessageOptions::_internal_deprecated() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.map_entry_ = false;
+ _impl_._has_bits_[0] &= ~0x00000008u;
+}
+inline bool MessageOptions::_internal_map_entry() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ _impl_.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 _impl_.uninterpreted_option_.size();
+}
+inline int MessageOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void MessageOptions::clear_uninterpreted_option() {
+ _impl_.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 _impl_.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 &_impl_.uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& MessageOptions::_internal_uninterpreted_option(int index) const {
+ return _impl_.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 _impl_.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 _impl_.uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// FieldOptions
+
+// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+inline bool FieldOptions::_internal_has_ctype() const {
+ bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool FieldOptions::has_ctype() const {
+ return _internal_has_ctype();
+}
+inline void FieldOptions::clear_ctype() {
+ _impl_.ctype_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType FieldOptions::_internal_ctype() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType >(_impl_.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));
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool FieldOptions::has_packed() const {
+ return _internal_has_packed();
+}
+inline void FieldOptions::clear_packed() {
+ _impl_.packed_ = false;
+ _impl_._has_bits_[0] &= ~0x00000004u;
+}
+inline bool FieldOptions::_internal_packed() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool FieldOptions::has_jstype() const {
+ return _internal_has_jstype();
+}
+inline void FieldOptions::clear_jstype() {
+ _impl_.jstype_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType FieldOptions::_internal_jstype() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType >(_impl_.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));
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000008u) != 0;
+ return value;
+}
+inline bool FieldOptions::has_lazy() const {
+ return _internal_has_lazy();
+}
+inline void FieldOptions::clear_lazy() {
+ _impl_.lazy_ = false;
+ _impl_._has_bits_[0] &= ~0x00000008u;
+}
+inline bool FieldOptions::_internal_lazy() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ _impl_.lazy_ = value;
+}
+inline void FieldOptions::set_lazy(bool value) {
+ _internal_set_lazy(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.lazy)
+}
+
+// optional bool unverified_lazy = 15 [default = false];
+inline bool FieldOptions::_internal_has_unverified_lazy() const {
+ bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
+ return value;
+}
+inline bool FieldOptions::has_unverified_lazy() const {
+ return _internal_has_unverified_lazy();
+}
+inline void FieldOptions::clear_unverified_lazy() {
+ _impl_.unverified_lazy_ = false;
+ _impl_._has_bits_[0] &= ~0x00000010u;
+}
+inline bool FieldOptions::_internal_unverified_lazy() const {
+ return _impl_.unverified_lazy_;
+}
+inline bool FieldOptions::unverified_lazy() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.unverified_lazy)
+ return _internal_unverified_lazy();
+}
+inline void FieldOptions::_internal_set_unverified_lazy(bool value) {
+ _impl_._has_bits_[0] |= 0x00000010u;
+ _impl_.unverified_lazy_ = value;
+}
+inline void FieldOptions::set_unverified_lazy(bool value) {
+ _internal_set_unverified_lazy(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.unverified_lazy)
+}
+
+// optional bool deprecated = 3 [default = false];
+inline bool FieldOptions::_internal_has_deprecated() const {
+ bool value = (_impl_._has_bits_[0] & 0x00000020u) != 0;
+ return value;
+}
+inline bool FieldOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void FieldOptions::clear_deprecated() {
+ _impl_.deprecated_ = false;
+ _impl_._has_bits_[0] &= ~0x00000020u;
+}
+inline bool FieldOptions::_internal_deprecated() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000020u;
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000040u) != 0;
+ return value;
+}
+inline bool FieldOptions::has_weak() const {
+ return _internal_has_weak();
+}
+inline void FieldOptions::clear_weak() {
+ _impl_.weak_ = false;
+ _impl_._has_bits_[0] &= ~0x00000040u;
+}
+inline bool FieldOptions::_internal_weak() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000040u;
+ _impl_.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 _impl_.uninterpreted_option_.size();
+}
+inline int FieldOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void FieldOptions::clear_uninterpreted_option() {
+ _impl_.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 _impl_.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 &_impl_.uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& FieldOptions::_internal_uninterpreted_option(int index) const {
+ return _impl_.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 _impl_.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 _impl_.uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// OneofOptions
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int OneofOptions::_internal_uninterpreted_option_size() const {
+ return _impl_.uninterpreted_option_.size();
+}
+inline int OneofOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void OneofOptions::clear_uninterpreted_option() {
+ _impl_.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 _impl_.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 &_impl_.uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& OneofOptions::_internal_uninterpreted_option(int index) const {
+ return _impl_.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 _impl_.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 _impl_.uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// EnumOptions
+
+// optional bool allow_alias = 2;
+inline bool EnumOptions::_internal_has_allow_alias() const {
+ bool value = (_impl_._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() {
+ _impl_.allow_alias_ = false;
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline bool EnumOptions::_internal_allow_alias() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.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 = (_impl_._has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool EnumOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void EnumOptions::clear_deprecated() {
+ _impl_.deprecated_ = false;
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline bool EnumOptions::_internal_deprecated() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.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 _impl_.uninterpreted_option_.size();
+}
+inline int EnumOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void EnumOptions::clear_uninterpreted_option() {
+ _impl_.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 _impl_.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 &_impl_.uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& EnumOptions::_internal_uninterpreted_option(int index) const {
+ return _impl_.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 _impl_.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 _impl_.uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// EnumValueOptions
+
+// optional bool deprecated = 1 [default = false];
+inline bool EnumValueOptions::_internal_has_deprecated() const {
+ bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool EnumValueOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void EnumValueOptions::clear_deprecated() {
+ _impl_.deprecated_ = false;
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline bool EnumValueOptions::_internal_deprecated() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.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 _impl_.uninterpreted_option_.size();
+}
+inline int EnumValueOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void EnumValueOptions::clear_uninterpreted_option() {
+ _impl_.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 _impl_.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 &_impl_.uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& EnumValueOptions::_internal_uninterpreted_option(int index) const {
+ return _impl_.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 _impl_.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 _impl_.uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// ServiceOptions
+
+// optional bool deprecated = 33 [default = false];
+inline bool ServiceOptions::_internal_has_deprecated() const {
+ bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool ServiceOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void ServiceOptions::clear_deprecated() {
+ _impl_.deprecated_ = false;
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline bool ServiceOptions::_internal_deprecated() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.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 _impl_.uninterpreted_option_.size();
+}
+inline int ServiceOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void ServiceOptions::clear_uninterpreted_option() {
+ _impl_.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 _impl_.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 &_impl_.uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& ServiceOptions::_internal_uninterpreted_option(int index) const {
+ return _impl_.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 _impl_.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 _impl_.uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// MethodOptions
+
+// optional bool deprecated = 33 [default = false];
+inline bool MethodOptions::_internal_has_deprecated() const {
+ bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool MethodOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void MethodOptions::clear_deprecated() {
+ _impl_.deprecated_ = false;
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline bool MethodOptions::_internal_deprecated() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.idempotency_level_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel MethodOptions::_internal_idempotency_level() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel >(_impl_.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));
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.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 _impl_.uninterpreted_option_.size();
+}
+inline int MethodOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void MethodOptions::clear_uninterpreted_option() {
+ _impl_.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 _impl_.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 &_impl_.uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& MethodOptions::_internal_uninterpreted_option(int index) const {
+ return _impl_.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 _impl_.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 _impl_.uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// UninterpretedOption_NamePart
+
+// required string name_part = 1;
+inline bool UninterpretedOption_NamePart::_internal_has_name_part() const {
+ bool value = (_impl_._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() {
+ _impl_.name_part_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_part_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.name_part)
+}
+inline std::string* UninterpretedOption_NamePart::mutable_name_part() {
+ std::string* _s = _internal_mutable_name_part();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.NamePart.name_part)
+ return _s;
+}
+inline const std::string& UninterpretedOption_NamePart::_internal_name_part() const {
+ return _impl_.name_part_.Get();
+}
+inline void UninterpretedOption_NamePart::_internal_set_name_part(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.name_part_.Set(value, GetArenaForAllocation());
+}
+inline std::string* UninterpretedOption_NamePart::_internal_mutable_name_part() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ return _impl_.name_part_.Mutable(GetArenaForAllocation());
+}
+inline std::string* UninterpretedOption_NamePart::release_name_part() {
+ // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.NamePart.name_part)
+ if (!_internal_has_name_part()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ auto* p = _impl_.name_part_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_part_.IsDefault()) {
+ _impl_.name_part_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void UninterpretedOption_NamePart::set_allocated_name_part(std::string* name_part) {
+ if (name_part != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.name_part_.SetAllocated(name_part, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_part_.IsDefault()) {
+ _impl_.name_part_.Set("", 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 = (_impl_._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() {
+ _impl_.is_extension_ = false;
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline bool UninterpretedOption_NamePart::_internal_is_extension() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.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 _impl_.name_.size();
+}
+inline int UninterpretedOption::name_size() const {
+ return _internal_name_size();
+}
+inline void UninterpretedOption::clear_name() {
+ _impl_.name_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.name)
+ return _impl_.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 &_impl_.name_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart& UninterpretedOption::_internal_name(int index) const {
+ return _impl_.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 _impl_.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 _impl_.name_;
+}
+
+// optional string identifier_value = 3;
+inline bool UninterpretedOption::_internal_has_identifier_value() const {
+ bool value = (_impl_._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() {
+ _impl_.identifier_value_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.identifier_value_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.identifier_value)
+}
+inline std::string* UninterpretedOption::mutable_identifier_value() {
+ std::string* _s = _internal_mutable_identifier_value();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.identifier_value)
+ return _s;
+}
+inline const std::string& UninterpretedOption::_internal_identifier_value() const {
+ return _impl_.identifier_value_.Get();
+}
+inline void UninterpretedOption::_internal_set_identifier_value(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.identifier_value_.Set(value, GetArenaForAllocation());
+}
+inline std::string* UninterpretedOption::_internal_mutable_identifier_value() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ return _impl_.identifier_value_.Mutable(GetArenaForAllocation());
+}
+inline std::string* UninterpretedOption::release_identifier_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.identifier_value)
+ if (!_internal_has_identifier_value()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ auto* p = _impl_.identifier_value_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.identifier_value_.IsDefault()) {
+ _impl_.identifier_value_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void UninterpretedOption::set_allocated_identifier_value(std::string* identifier_value) {
+ if (identifier_value != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.identifier_value_.SetAllocated(identifier_value, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.identifier_value_.IsDefault()) {
+ _impl_.identifier_value_.Set("", 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 = (_impl_._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() {
+ _impl_.positive_int_value_ = uint64_t{0u};
+ _impl_._has_bits_[0] &= ~0x00000008u;
+}
+inline uint64_t UninterpretedOption::_internal_positive_int_value() const {
+ return _impl_.positive_int_value_;
+}
+inline uint64_t 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(uint64_t value) {
+ _impl_._has_bits_[0] |= 0x00000008u;
+ _impl_.positive_int_value_ = value;
+}
+inline void UninterpretedOption::set_positive_int_value(uint64_t 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 = (_impl_._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() {
+ _impl_.negative_int_value_ = int64_t{0};
+ _impl_._has_bits_[0] &= ~0x00000010u;
+}
+inline int64_t UninterpretedOption::_internal_negative_int_value() const {
+ return _impl_.negative_int_value_;
+}
+inline int64_t 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(int64_t value) {
+ _impl_._has_bits_[0] |= 0x00000010u;
+ _impl_.negative_int_value_ = value;
+}
+inline void UninterpretedOption::set_negative_int_value(int64_t 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 = (_impl_._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() {
+ _impl_.double_value_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000020u;
+}
+inline double UninterpretedOption::_internal_double_value() const {
+ return _impl_.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) {
+ _impl_._has_bits_[0] |= 0x00000020u;
+ _impl_.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 = (_impl_._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() {
+ _impl_.string_value_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.string_value_.SetBytes(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.string_value)
+}
+inline std::string* UninterpretedOption::mutable_string_value() {
+ std::string* _s = _internal_mutable_string_value();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.string_value)
+ return _s;
+}
+inline const std::string& UninterpretedOption::_internal_string_value() const {
+ return _impl_.string_value_.Get();
+}
+inline void UninterpretedOption::_internal_set_string_value(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.string_value_.Set(value, GetArenaForAllocation());
+}
+inline std::string* UninterpretedOption::_internal_mutable_string_value() {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ return _impl_.string_value_.Mutable(GetArenaForAllocation());
+}
+inline std::string* UninterpretedOption::release_string_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.string_value)
+ if (!_internal_has_string_value()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ auto* p = _impl_.string_value_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.string_value_.IsDefault()) {
+ _impl_.string_value_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void UninterpretedOption::set_allocated_string_value(std::string* string_value) {
+ if (string_value != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ _impl_.string_value_.SetAllocated(string_value, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.string_value_.IsDefault()) {
+ _impl_.string_value_.Set("", 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 = (_impl_._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() {
+ _impl_.aggregate_value_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000004u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.aggregate_value_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.aggregate_value)
+}
+inline std::string* UninterpretedOption::mutable_aggregate_value() {
+ std::string* _s = _internal_mutable_aggregate_value();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.aggregate_value)
+ return _s;
+}
+inline const std::string& UninterpretedOption::_internal_aggregate_value() const {
+ return _impl_.aggregate_value_.Get();
+}
+inline void UninterpretedOption::_internal_set_aggregate_value(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.aggregate_value_.Set(value, GetArenaForAllocation());
+}
+inline std::string* UninterpretedOption::_internal_mutable_aggregate_value() {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ return _impl_.aggregate_value_.Mutable(GetArenaForAllocation());
+}
+inline std::string* UninterpretedOption::release_aggregate_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.aggregate_value)
+ if (!_internal_has_aggregate_value()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000004u;
+ auto* p = _impl_.aggregate_value_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.aggregate_value_.IsDefault()) {
+ _impl_.aggregate_value_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void UninterpretedOption::set_allocated_aggregate_value(std::string* aggregate_value) {
+ if (aggregate_value != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000004u;
+ }
+ _impl_.aggregate_value_.SetAllocated(aggregate_value, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.aggregate_value_.IsDefault()) {
+ _impl_.aggregate_value_.Set("", 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 _impl_.path_.size();
+}
+inline int SourceCodeInfo_Location::path_size() const {
+ return _internal_path_size();
+}
+inline void SourceCodeInfo_Location::clear_path() {
+ _impl_.path_.Clear();
+}
+inline int32_t SourceCodeInfo_Location::_internal_path(int index) const {
+ return _impl_.path_.Get(index);
+}
+inline int32_t 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, int32_t value) {
+ _impl_.path_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.path)
+}
+inline void SourceCodeInfo_Location::_internal_add_path(int32_t value) {
+ _impl_.path_.Add(value);
+}
+inline void SourceCodeInfo_Location::add_path(int32_t value) {
+ _internal_add_path(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.path)
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+SourceCodeInfo_Location::_internal_path() const {
+ return _impl_.path_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+SourceCodeInfo_Location::path() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.path)
+ return _internal_path();
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+SourceCodeInfo_Location::_internal_mutable_path() {
+ return &_impl_.path_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+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 _impl_.span_.size();
+}
+inline int SourceCodeInfo_Location::span_size() const {
+ return _internal_span_size();
+}
+inline void SourceCodeInfo_Location::clear_span() {
+ _impl_.span_.Clear();
+}
+inline int32_t SourceCodeInfo_Location::_internal_span(int index) const {
+ return _impl_.span_.Get(index);
+}
+inline int32_t 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, int32_t value) {
+ _impl_.span_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.span)
+}
+inline void SourceCodeInfo_Location::_internal_add_span(int32_t value) {
+ _impl_.span_.Add(value);
+}
+inline void SourceCodeInfo_Location::add_span(int32_t value) {
+ _internal_add_span(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.span)
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+SourceCodeInfo_Location::_internal_span() const {
+ return _impl_.span_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+SourceCodeInfo_Location::span() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.span)
+ return _internal_span();
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+SourceCodeInfo_Location::_internal_mutable_span() {
+ return &_impl_.span_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+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 = (_impl_._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() {
+ _impl_.leading_comments_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.leading_comments_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+inline std::string* SourceCodeInfo_Location::mutable_leading_comments() {
+ std::string* _s = _internal_mutable_leading_comments();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_comments)
+ return _s;
+}
+inline const std::string& SourceCodeInfo_Location::_internal_leading_comments() const {
+ return _impl_.leading_comments_.Get();
+}
+inline void SourceCodeInfo_Location::_internal_set_leading_comments(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.leading_comments_.Set(value, GetArenaForAllocation());
+}
+inline std::string* SourceCodeInfo_Location::_internal_mutable_leading_comments() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ return _impl_.leading_comments_.Mutable(GetArenaForAllocation());
+}
+inline std::string* SourceCodeInfo_Location::release_leading_comments() {
+ // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.leading_comments)
+ if (!_internal_has_leading_comments()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ auto* p = _impl_.leading_comments_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.leading_comments_.IsDefault()) {
+ _impl_.leading_comments_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void SourceCodeInfo_Location::set_allocated_leading_comments(std::string* leading_comments) {
+ if (leading_comments != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.leading_comments_.SetAllocated(leading_comments, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.leading_comments_.IsDefault()) {
+ _impl_.leading_comments_.Set("", 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 = (_impl_._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() {
+ _impl_.trailing_comments_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.trailing_comments_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+inline std::string* SourceCodeInfo_Location::mutable_trailing_comments() {
+ std::string* _s = _internal_mutable_trailing_comments();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+ return _s;
+}
+inline const std::string& SourceCodeInfo_Location::_internal_trailing_comments() const {
+ return _impl_.trailing_comments_.Get();
+}
+inline void SourceCodeInfo_Location::_internal_set_trailing_comments(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.trailing_comments_.Set(value, GetArenaForAllocation());
+}
+inline std::string* SourceCodeInfo_Location::_internal_mutable_trailing_comments() {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ return _impl_.trailing_comments_.Mutable(GetArenaForAllocation());
+}
+inline std::string* SourceCodeInfo_Location::release_trailing_comments() {
+ // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+ if (!_internal_has_trailing_comments()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ auto* p = _impl_.trailing_comments_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.trailing_comments_.IsDefault()) {
+ _impl_.trailing_comments_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void SourceCodeInfo_Location::set_allocated_trailing_comments(std::string* trailing_comments) {
+ if (trailing_comments != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000002u;
+ }
+ _impl_.trailing_comments_.SetAllocated(trailing_comments, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.trailing_comments_.IsDefault()) {
+ _impl_.trailing_comments_.Set("", 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 _impl_.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() {
+ _impl_.leading_detached_comments_.Clear();
+}
+inline std::string* SourceCodeInfo_Location::add_leading_detached_comments() {
+ std::string* _s = _internal_add_leading_detached_comments();
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+ return _s;
+}
+inline const std::string& SourceCodeInfo_Location::_internal_leading_detached_comments(int index) const {
+ return _impl_.leading_detached_comments_.Get(index);
+}
+inline const std::string& 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 std::string* SourceCodeInfo_Location::mutable_leading_detached_comments(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+ return _impl_.leading_detached_comments_.Mutable(index);
+}
+inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const std::string& value) {
+ _impl_.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, std::string&& value) {
+ _impl_.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);
+ _impl_.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) {
+ _impl_.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 std::string* SourceCodeInfo_Location::_internal_add_leading_detached_comments() {
+ return _impl_.leading_detached_comments_.Add();
+}
+inline void SourceCodeInfo_Location::add_leading_detached_comments(const std::string& value) {
+ _impl_.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(std::string&& value) {
+ _impl_.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);
+ _impl_.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) {
+ _impl_.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<std::string>&
+SourceCodeInfo_Location::leading_detached_comments() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+ return _impl_.leading_detached_comments_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
+SourceCodeInfo_Location::mutable_leading_detached_comments() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+ return &_impl_.leading_detached_comments_;
+}
+
+// -------------------------------------------------------------------
+
+// SourceCodeInfo
+
+// repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+inline int SourceCodeInfo::_internal_location_size() const {
+ return _impl_.location_.size();
+}
+inline int SourceCodeInfo::location_size() const {
+ return _internal_location_size();
+}
+inline void SourceCodeInfo::clear_location() {
+ _impl_.location_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.location)
+ return _impl_.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 &_impl_.location_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location& SourceCodeInfo::_internal_location(int index) const {
+ return _impl_.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 _impl_.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 _impl_.location_;
+}
+
+// -------------------------------------------------------------------
+
+// GeneratedCodeInfo_Annotation
+
+// repeated int32 path = 1 [packed = true];
+inline int GeneratedCodeInfo_Annotation::_internal_path_size() const {
+ return _impl_.path_.size();
+}
+inline int GeneratedCodeInfo_Annotation::path_size() const {
+ return _internal_path_size();
+}
+inline void GeneratedCodeInfo_Annotation::clear_path() {
+ _impl_.path_.Clear();
+}
+inline int32_t GeneratedCodeInfo_Annotation::_internal_path(int index) const {
+ return _impl_.path_.Get(index);
+}
+inline int32_t 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, int32_t value) {
+ _impl_.path_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.path)
+}
+inline void GeneratedCodeInfo_Annotation::_internal_add_path(int32_t value) {
+ _impl_.path_.Add(value);
+}
+inline void GeneratedCodeInfo_Annotation::add_path(int32_t value) {
+ _internal_add_path(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.GeneratedCodeInfo.Annotation.path)
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+GeneratedCodeInfo_Annotation::_internal_path() const {
+ return _impl_.path_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
+GeneratedCodeInfo_Annotation::path() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.GeneratedCodeInfo.Annotation.path)
+ return _internal_path();
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+GeneratedCodeInfo_Annotation::_internal_mutable_path() {
+ return &_impl_.path_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
+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 = (_impl_._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() {
+ _impl_.source_file_.ClearToEmpty();
+ _impl_._has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& 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) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.source_file_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+}
+inline std::string* GeneratedCodeInfo_Annotation::mutable_source_file() {
+ std::string* _s = _internal_mutable_source_file();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+ return _s;
+}
+inline const std::string& GeneratedCodeInfo_Annotation::_internal_source_file() const {
+ return _impl_.source_file_.Get();
+}
+inline void GeneratedCodeInfo_Annotation::_internal_set_source_file(const std::string& value) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ _impl_.source_file_.Set(value, GetArenaForAllocation());
+}
+inline std::string* GeneratedCodeInfo_Annotation::_internal_mutable_source_file() {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ return _impl_.source_file_.Mutable(GetArenaForAllocation());
+}
+inline std::string* GeneratedCodeInfo_Annotation::release_source_file() {
+ // @@protoc_insertion_point(field_release:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+ if (!_internal_has_source_file()) {
+ return nullptr;
+ }
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ auto* p = _impl_.source_file_.Release();
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.source_file_.IsDefault()) {
+ _impl_.source_file_.Set("", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void GeneratedCodeInfo_Annotation::set_allocated_source_file(std::string* source_file) {
+ if (source_file != nullptr) {
+ _impl_._has_bits_[0] |= 0x00000001u;
+ } else {
+ _impl_._has_bits_[0] &= ~0x00000001u;
+ }
+ _impl_.source_file_.SetAllocated(source_file, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.source_file_.IsDefault()) {
+ _impl_.source_file_.Set("", 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 = (_impl_._has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool GeneratedCodeInfo_Annotation::has_begin() const {
+ return _internal_has_begin();
+}
+inline void GeneratedCodeInfo_Annotation::clear_begin() {
+ _impl_.begin_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000002u;
+}
+inline int32_t GeneratedCodeInfo_Annotation::_internal_begin() const {
+ return _impl_.begin_;
+}
+inline int32_t GeneratedCodeInfo_Annotation::begin() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.begin)
+ return _internal_begin();
+}
+inline void GeneratedCodeInfo_Annotation::_internal_set_begin(int32_t value) {
+ _impl_._has_bits_[0] |= 0x00000002u;
+ _impl_.begin_ = value;
+}
+inline void GeneratedCodeInfo_Annotation::set_begin(int32_t 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 = (_impl_._has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool GeneratedCodeInfo_Annotation::has_end() const {
+ return _internal_has_end();
+}
+inline void GeneratedCodeInfo_Annotation::clear_end() {
+ _impl_.end_ = 0;
+ _impl_._has_bits_[0] &= ~0x00000004u;
+}
+inline int32_t GeneratedCodeInfo_Annotation::_internal_end() const {
+ return _impl_.end_;
+}
+inline int32_t GeneratedCodeInfo_Annotation::end() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.end)
+ return _internal_end();
+}
+inline void GeneratedCodeInfo_Annotation::_internal_set_end(int32_t value) {
+ _impl_._has_bits_[0] |= 0x00000004u;
+ _impl_.end_ = value;
+}
+inline void GeneratedCodeInfo_Annotation::set_end(int32_t 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 _impl_.annotation_.size();
+}
+inline int GeneratedCodeInfo::annotation_size() const {
+ return _internal_annotation_size();
+}
+inline void GeneratedCodeInfo::clear_annotation() {
+ _impl_.annotation_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::mutable_annotation(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.annotation)
+ return _impl_.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 &_impl_.annotation_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation& GeneratedCodeInfo::_internal_annotation(int index) const {
+ return _impl_.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 _impl_.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 _impl_.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/toolkit/components/protobuf/src/google/protobuf/descriptor.proto b/toolkit/components/protobuf/src/google/protobuf/descriptor.proto
new file mode 100644
index 0000000000..f8eb216cdc
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/descriptor.proto
@@ -0,0 +1,921 @@
+// 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.
+ 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.
+ //
+ // As of 2021, lazy does no correctness checks on the byte stream during
+ // parsing. This may lead to crashes if and when an invalid byte stream is
+ // finally parsed upon access.
+ //
+ // TODO(b/211906113): Enable validation on lazy fields.
+ optional bool lazy = 5 [default = false];
+
+ // unverified_lazy does no correctness checks on the byte stream. This should
+ // only be used where lazy with verification is prohibitive for performance
+ // reasons.
+ optional bool unverified_lazy = 15 [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], ["moo", false] } represents
+ // "foo.(bar.baz).moo".
+ 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 occurs.
+ // 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 moo.
+ // //
+ // // Another line attached to moo.
+ // optional double moo = 4;
+ //
+ // // Detached comment for corge. This is not leading or trailing comments
+ // // to moo 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/toolkit/components/protobuf/src/google/protobuf/descriptor_database.cc b/toolkit/components/protobuf/src/google/protobuf/descriptor_database.cc
new file mode 100644
index 0000000000..203000d67d
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/descriptor_database.cc
@@ -0,0 +1,1048 @@
+// 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 <algorithm>
+#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 std::string& prefix,
+ std::set<std::string>* output) {
+ GOOGLE_CHECK(desc_proto.has_name());
+ std::string 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<std::string>* 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<std::string>* output) {
+ std::vector<std::string> file_names;
+ if (!db->FindAllFileNames(&file_names)) {
+ return false;
+ }
+ std::set<std::string> 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<std::string>* output) {
+ return ForAllFileProtos(
+ this,
+ [](const FileDescriptorProto& file_proto, std::set<std::string>* set) {
+ set->insert(file_proto.package());
+ },
+ output);
+}
+
+bool DescriptorDatabase::FindAllMessageNames(std::vector<std::string>* output) {
+ return ForAllFileProtos(
+ this,
+ [](const FileDescriptorProto& file_proto, std::set<std::string>* 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.
+ std::string path = file.has_package() ? file.package() : std::string();
+ 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 std::string& 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<std::string, 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<std::string, Value>::value_type(name, value));
+
+ return true;
+}
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddNestedExtensions(
+ const std::string& 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 std::string& 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 std::string& filename) {
+ return FindWithDefault(by_name_, filename, Value());
+}
+
+template <typename Value>
+Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindSymbol(
+ const std::string& 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 std::string& 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 std::string& containing_type, std::vector<int>* output) {
+ typename std::map<std::pair<std::string, 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<std::string>* 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 std::string& filename,
+ FileDescriptorProto* output) {
+ return MaybeCopy(index_.FindFile(filename), output);
+}
+
+bool SimpleDescriptorDatabase::FindFileContainingSymbol(
+ const std::string& symbol_name, FileDescriptorProto* output) {
+ return MaybeCopy(index_.FindSymbol(symbol_name), output);
+}
+
+bool SimpleDescriptorDatabase::FindFileContainingExtension(
+ const std::string& containing_type, int field_number,
+ FileDescriptorProto* output) {
+ return MaybeCopy(index_.FindExtension(containing_type, field_number), output);
+}
+
+bool SimpleDescriptorDatabase::FindAllExtensionNumbers(
+ const std::string& extendee_type, std::vector<int>* output) {
+ return index_.FindAllExtensionNumbers(extendee_type, output);
+}
+
+
+bool SimpleDescriptorDatabase::FindAllFileNames(
+ std::vector<std::string>* 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<std::string>* 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 = std::string;
+
+ 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);
+ }
+
+ std::string AsString(const DescriptorIndex& index) const {
+ auto p = package(index);
+ return StrCat(p, p.empty() ? "" : ".", symbol(index));
+ }
+ };
+
+ struct SymbolCompare {
+ const DescriptorIndex& index;
+
+ std::string 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 std::string& filename,
+ FileDescriptorProto* output) {
+ return MaybeParse(index_->FindFile(filename), output);
+}
+
+bool EncodedDescriptorDatabase::FindFileContainingSymbol(
+ const std::string& symbol_name, FileDescriptorProto* output) {
+ return MaybeParse(index_->FindSymbol(symbol_name), output);
+}
+
+bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol(
+ const std::string& symbol_name, std::string* 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 uint32_t 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 std::string& containing_type, int field_number,
+ FileDescriptorProto* output) {
+ return MaybeParse(index_->FindExtension(containing_type, field_number),
+ output);
+}
+
+bool EncodedDescriptorDatabase::FindAllExtensionNumbers(
+ const std::string& 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)};
+ std::string 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<std::string>* output) const {
+ output->resize(by_name_.size() + by_name_flat_.size());
+ int i = 0;
+ for (const auto& entry : by_name_) {
+ (*output)[i] = std::string(entry.name(*this));
+ i++;
+ }
+ for (const auto& entry : by_name_flat_) {
+ (*output)[i] = std::string(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<std::string>* 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 std::string& 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 std::string& 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 std::string& 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 std::string& 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 std::string& filename,
+ FileDescriptorProto* output) {
+ for (DescriptorDatabase* source : sources_) {
+ if (source->FindFileByName(filename, output)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool MergedDescriptorDatabase::FindFileContainingSymbol(
+ const std::string& 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 std::string& 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 std::string& 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;
+}
+
+
+bool MergedDescriptorDatabase::FindAllFileNames(
+ std::vector<std::string>* output) {
+ bool implemented = false;
+ for (DescriptorDatabase* source : sources_) {
+ std::vector<std::string> source_output;
+ if (source->FindAllFileNames(&source_output)) {
+ output->reserve(output->size() + source_output.size());
+ for (auto& source : source_output) {
+ output->push_back(std::move(source));
+ }
+ implemented = true;
+ }
+ }
+ return implemented;
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/toolkit/components/protobuf/src/google/protobuf/descriptor_database.h b/toolkit/components/protobuf/src/google/protobuf/descriptor_database.h
new file mode 100644
index 0000000000..f4f06bbfa6
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/descriptor_database.h
@@ -0,0 +1,398 @@
+// 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>
+
+// Must be included last.
+#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 std::string& 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 std::string& 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 std::string& 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 std::string& /* 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<std::string>* /*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<std::string>* 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<std::string>* 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 std::string& filename,
+ FileDescriptorProto* output) override;
+ bool FindFileContainingSymbol(const std::string& symbol_name,
+ FileDescriptorProto* output) override;
+ bool FindFileContainingExtension(const std::string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) override;
+ bool FindAllExtensionNumbers(const std::string& extendee_type,
+ std::vector<int>* output) override;
+
+ bool FindAllFileNames(std::vector<std::string>* 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 std::string& name, Value value);
+ bool AddNestedExtensions(const std::string& filename,
+ const DescriptorProto& message_type, Value value);
+ bool AddExtension(const std::string& filename,
+ const FieldDescriptorProto& field, Value value);
+
+ Value FindFile(const std::string& filename);
+ Value FindSymbol(const std::string& name);
+ Value FindExtension(const std::string& containing_type, int field_number);
+ bool FindAllExtensionNumbers(const std::string& containing_type,
+ std::vector<int>* output);
+ void FindAllFileNames(std::vector<std::string>* output);
+
+ private:
+ std::map<std::string, Value> by_name_;
+ std::map<std::string, Value> by_symbol_;
+ std::map<std::pair<std::string, 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 std::string& symbol_name,
+ std::string* output);
+
+ // implements DescriptorDatabase -----------------------------------
+ bool FindFileByName(const std::string& filename,
+ FileDescriptorProto* output) override;
+ bool FindFileContainingSymbol(const std::string& symbol_name,
+ FileDescriptorProto* output) override;
+ bool FindFileContainingExtension(const std::string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) override;
+ bool FindAllExtensionNumbers(const std::string& extendee_type,
+ std::vector<int>* output) override;
+ bool FindAllFileNames(std::vector<std::string>* 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 std::string& filename,
+ FileDescriptorProto* output) override;
+ bool FindFileContainingSymbol(const std::string& symbol_name,
+ FileDescriptorProto* output) override;
+ bool FindFileContainingExtension(const std::string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) override;
+ bool FindAllExtensionNumbers(const std::string& 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 std::string& filename,
+ FileDescriptorProto* output) override;
+ bool FindFileContainingSymbol(const std::string& symbol_name,
+ FileDescriptorProto* output) override;
+ bool FindFileContainingExtension(const std::string& 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 std::string& extendee_type,
+ std::vector<int>* output) override;
+
+
+ // This function is best-effort. Returns true if at least one underlying
+ // DescriptorDatabase returns true.
+ bool FindAllFileNames(std::vector<std::string>* 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/toolkit/components/protobuf/src/google/protobuf/duration.pb.cc b/toolkit/components/protobuf/src/google/protobuf/duration.pb.cc
new file mode 100644
index 0000000000..72766bd3b4
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/duration.pb.cc
@@ -0,0 +1,307 @@
+// 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
+
+namespace _pb = ::PROTOBUF_NAMESPACE_ID;
+namespace _pbi = _pb::internal;
+
+PROTOBUF_NAMESPACE_OPEN
+PROTOBUF_CONSTEXPR Duration::Duration(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.seconds_)*/int64_t{0}
+ , /*decltype(_impl_.nanos_)*/0
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct DurationDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR DurationDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~DurationDefaultTypeInternal() {}
+ union {
+ Duration _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 DurationDefaultTypeInternal _Duration_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fduration_2eproto[1];
+static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr;
+static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr;
+
+const uint32_t 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, _impl_.seconds_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Duration, _impl_.nanos_),
+};
+static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Duration)},
+};
+
+static const ::_pb::Message* const file_default_instances[] = {
+ &::PROTOBUF_NAMESPACE_ID::_Duration_default_instance_._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 ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fduration_2eproto_once;
+const ::_pbi::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 ::_pbi::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_PRIORITY2 static ::_pbi::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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Duration)
+}
+Duration::Duration(const Duration& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Duration* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.seconds_){}
+ , decltype(_impl_.nanos_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ ::memcpy(&_impl_.seconds_, &from._impl_.seconds_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.nanos_) -
+ reinterpret_cast<char*>(&_impl_.seconds_)) + sizeof(_impl_.nanos_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Duration)
+}
+
+inline void Duration::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.seconds_){int64_t{0}}
+ , decltype(_impl_.nanos_){0}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+Duration::~Duration() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Duration)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Duration::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void Duration::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void Duration::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Duration)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ ::memset(&_impl_.seconds_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.nanos_) -
+ reinterpret_cast<char*>(&_impl_.seconds_)) + sizeof(_impl_.nanos_));
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Duration::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // int64 seconds = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _impl_.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)) {
+ _impl_.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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // int64 seconds = 1;
+ if (this->_internal_seconds() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteInt64ToArray(1, this->_internal_seconds(), target);
+ }
+
+ // int32 nanos = 2;
+ if (this->_internal_nanos() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_nanos(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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 += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_seconds());
+ }
+
+ // int32 nanos = 2;
+ if (this->_internal_nanos() != 0) {
+ total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_nanos());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Duration::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Duration::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Duration::GetClassData() const { return &_class_data_; }
+
+
+void Duration::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Duration*>(&to_msg);
+ auto& from = static_cast<const Duration&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Duration)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_seconds() != 0) {
+ _this->_internal_set_seconds(from._internal_seconds());
+ }
+ if (from._internal_nanos() != 0) {
+ _this->_internal_set_nanos(from._internal_nanos());
+ }
+ _this->_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, _impl_.nanos_)
+ + sizeof(Duration::_impl_.nanos_)
+ - PROTOBUF_FIELD_OFFSET(Duration, _impl_.seconds_)>(
+ reinterpret_cast<char*>(&_impl_.seconds_),
+ reinterpret_cast<char*>(&other->_impl_.seconds_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Duration::GetMetadata() const {
+ return ::_pbi::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/toolkit/components/protobuf/src/google/protobuf/duration.pb.h b/toolkit/components/protobuf/src/google/protobuf/duration.pb.h
new file mode 100644
index 0000000000..c4a94c5394
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/duration.pb.h
@@ -0,0 +1,278 @@
+// 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 < 3021000
+#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 3021006 < 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_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 uint32_t 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 PROTOBUF_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) {
+ Duration::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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();
+ int64_t seconds() const;
+ void set_seconds(int64_t value);
+ private:
+ int64_t _internal_seconds() const;
+ void _internal_set_seconds(int64_t value);
+ public:
+
+ // int32 nanos = 2;
+ void clear_nanos();
+ int32_t nanos() const;
+ void set_nanos(int32_t value);
+ private:
+ int32_t _internal_nanos() const;
+ void _internal_set_nanos(int32_t 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_;
+ struct Impl_ {
+ int64_t seconds_;
+ int32_t nanos_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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() {
+ _impl_.seconds_ = int64_t{0};
+}
+inline int64_t Duration::_internal_seconds() const {
+ return _impl_.seconds_;
+}
+inline int64_t Duration::seconds() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Duration.seconds)
+ return _internal_seconds();
+}
+inline void Duration::_internal_set_seconds(int64_t value) {
+
+ _impl_.seconds_ = value;
+}
+inline void Duration::set_seconds(int64_t value) {
+ _internal_set_seconds(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Duration.seconds)
+}
+
+// int32 nanos = 2;
+inline void Duration::clear_nanos() {
+ _impl_.nanos_ = 0;
+}
+inline int32_t Duration::_internal_nanos() const {
+ return _impl_.nanos_;
+}
+inline int32_t Duration::nanos() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Duration.nanos)
+ return _internal_nanos();
+}
+inline void Duration::_internal_set_nanos(int32_t value) {
+
+ _impl_.nanos_ = value;
+}
+inline void Duration::set_nanos(int32_t 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/toolkit/components/protobuf/src/google/protobuf/duration.proto b/toolkit/components/protobuf/src/google/protobuf/duration.proto
new file mode 100644
index 0000000000..81c3e369fd
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/dynamic_message.cc b/toolkit/components/protobuf/src/google/protobuf/dynamic_message.cc
new file mode 100644
index 0000000000..1c96ca2080
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/dynamic_message.cc
@@ -0,0 +1,826 @@
+// 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.h>
+#include <google/protobuf/descriptor.pb.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>
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+using internal::DynamicMapField;
+using internal::ExtensionSet;
+using internal::MapField;
+
+
+using internal::ArenaStringPtr;
+
+// ===================================================================
+// Some helper tables and functions...
+
+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<int32_t>);
+ case FD::CPPTYPE_INT64:
+ return sizeof(RepeatedField<int64_t>);
+ case FD::CPPTYPE_UINT32:
+ return sizeof(RepeatedField<uint32_t>);
+ case FD::CPPTYPE_UINT64:
+ return sizeof(RepeatedField<uint64_t>);
+ 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<std::string>);
+ }
+ break;
+ }
+ } else {
+ switch (field->cpp_type()) {
+ case FD::CPPTYPE_INT32:
+ return sizeof(int32_t);
+ case FD::CPPTYPE_INT64:
+ return sizeof(int64_t);
+ case FD::CPPTYPE_UINT32:
+ return sizeof(uint32_t);
+ case FD::CPPTYPE_UINT64:
+ return sizeof(uint64_t);
+ 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(uint64_t);
+static const int kMaxOneofUnionSize = sizeof(uint64_t);
+
+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() override;
+
+ // 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 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<uint32_t[]> offsets;
+ std::unique_ptr<uint32_t[]> 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<int32_t, 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(type_info_->offsets[i]);
+}
+inline void* DynamicMessage::MutableExtensionsRaw() {
+ return OffsetToPointer(type_info_->extensions_offset);
+}
+inline void* DynamicMessage::MutableWeakFieldMapRaw() {
+ return OffsetToPointer(type_info_->weak_field_map_offset);
+}
+inline void* DynamicMessage::MutableOneofCaseRaw(int i) {
+ return OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32_t) * i);
+}
+inline void* DynamicMessage::MutableOneofFieldRaw(const FieldDescriptor* f) {
+ return OffsetToPointer(type_info_->offsets[type_info_->type->field_count() +
+ f->containing_oneof()->index()]);
+}
+
+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++)) uint32_t{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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ 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()) {
+ ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr();
+ asp->InitDefault();
+ } else {
+ new (field_ptr)
+ RepeatedPtrField<std::string>(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 int32_t*>(field_ptr)) == field->number()) {
+ field_ptr = MutableOneofFieldRaw(field);
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ switch (field->options().ctype()) {
+ default:
+ case FieldOptions::STRING: {
+ reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy();
+ 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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ 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<std::string>*>(field_ptr)
+ ->~RepeatedPtrField<std::string>();
+ 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: {
+ reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy();
+ 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.
+ uint32_t* offsets = new uint32_t[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;
+ uint32_t* has_bits_indices = new uint32_t[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<uint32_t>(-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(uint32_t));
+ size += has_bits_array_size * sizeof(uint32_t);
+ 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(uint32_t);
+ 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/toolkit/components/protobuf/src/google/protobuf/dynamic_message.h b/toolkit/components/protobuf/src/google/protobuf/dynamic_message.h
new file mode 100644
index 0000000000..6fa64259ee
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/dynamic_message.h
@@ -0,0 +1,227 @@
+// 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/stubs/mutex.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/reflection.h>
+#include <google/protobuf/repeated_field.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+// Must be included last.
+#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() override;
+
+ // 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: {
+ int32_t first = reflection->GetInt32(*a, field_);
+ int32_t second = reflection->GetInt32(*b, field_);
+ return first < second;
+ }
+ case FieldDescriptor::CPPTYPE_INT64: {
+ int64_t first = reflection->GetInt64(*a, field_);
+ int64_t second = reflection->GetInt64(*b, field_);
+ return first < second;
+ }
+ case FieldDescriptor::CPPTYPE_UINT32: {
+ uint32_t first = reflection->GetUInt32(*a, field_);
+ uint32_t second = reflection->GetUInt32(*b, field_);
+ return first < second;
+ }
+ case FieldDescriptor::CPPTYPE_UINT64: {
+ uint64_t first = reflection->GetUInt64(*a, field_);
+ uint64_t second = reflection->GetUInt64(*b, field_);
+ return first < second;
+ }
+ case FieldDescriptor::CPPTYPE_STRING: {
+ std::string first = reflection->GetString(*a, field_);
+ std::string 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/toolkit/components/protobuf/src/google/protobuf/empty.pb.cc b/toolkit/components/protobuf/src/google/protobuf/empty.pb.cc
new file mode 100644
index 0000000000..3a30776386
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/empty.pb.cc
@@ -0,0 +1,130 @@
+// 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
+
+namespace _pb = ::PROTOBUF_NAMESPACE_ID;
+namespace _pbi = _pb::internal;
+
+PROTOBUF_NAMESPACE_OPEN
+PROTOBUF_CONSTEXPR Empty::Empty(
+ ::_pbi::ConstantInitialized) {}
+struct EmptyDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR EmptyDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~EmptyDefaultTypeInternal() {}
+ union {
+ Empty _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EmptyDefaultTypeInternal _Empty_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fempty_2eproto[1];
+static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr;
+static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr;
+
+const uint32_t 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 ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Empty)},
+};
+
+static const ::_pb::Message* const file_default_instances[] = {
+ &::PROTOBUF_NAMESPACE_ID::_Empty_default_instance_._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 ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fempty_2eproto_once;
+const ::_pbi::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 ::_pbi::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_PRIORITY2 static ::_pbi::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() {
+ Empty* const _this = this; (void)_this;
+ _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 ::_pbi::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/toolkit/components/protobuf/src/google/protobuf/empty.pb.h b/toolkit/components/protobuf/src/google/protobuf/empty.pb.h
new file mode 100644
index 0000000000..00a4481544
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/empty.pb.h
@@ -0,0 +1,198 @@
+// 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 < 3021000
+#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 3021006 < 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_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 uint32_t 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 PROTOBUF_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);
+ 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_;
+ struct Impl_ {
+ };
+ 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/toolkit/components/protobuf/src/google/protobuf/empty.proto b/toolkit/components/protobuf/src/google/protobuf/empty.proto
new file mode 100644
index 0000000000..2227462198
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/empty.proto
@@ -0,0 +1,51 @@
+// 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);
+// }
+//
+message Empty {}
diff --git a/toolkit/components/protobuf/src/google/protobuf/endian.h b/toolkit/components/protobuf/src/google/protobuf/endian.h
new file mode 100644
index 0000000000..e0ee6cdf28
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/endian.h
@@ -0,0 +1,198 @@
+// 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_ENDIAN_H__
+#define GOOGLE_PROTOBUF_ENDIAN_H__
+
+#if defined(_MSC_VER)
+#include <stdlib.h>
+#endif
+
+#include <cstdint>
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline uint64_t BSwap64(uint64_t host_int) {
+#if defined(PROTOBUF_BUILTIN_BSWAP64)
+ return PROTOBUF_BUILTIN_BSWAP64(host_int);
+#elif defined(_MSC_VER)
+ return _byteswap_uint64(host_int);
+#else
+ return (((host_int & uint64_t{0xFF}) << 56) |
+ ((host_int & uint64_t{0xFF00}) << 40) |
+ ((host_int & uint64_t{0xFF0000}) << 24) |
+ ((host_int & uint64_t{0xFF000000}) << 8) |
+ ((host_int & uint64_t{0xFF00000000}) >> 8) |
+ ((host_int & uint64_t{0xFF0000000000}) >> 24) |
+ ((host_int & uint64_t{0xFF000000000000}) >> 40) |
+ ((host_int & uint64_t{0xFF00000000000000}) >> 56));
+#endif
+}
+
+inline uint32_t BSwap32(uint32_t host_int) {
+#if defined(PROTOBUF_BUILTIN_BSWAP32)
+ return PROTOBUF_BUILTIN_BSWAP32(host_int);
+#elif defined(_MSC_VER)
+ return _byteswap_ulong(host_int);
+#else
+ return (((host_int & uint32_t{0xFF}) << 24) |
+ ((host_int & uint32_t{0xFF00}) << 8) |
+ ((host_int & uint32_t{0xFF0000}) >> 8) |
+ ((host_int & uint32_t{0xFF000000}) >> 24));
+#endif
+}
+
+inline uint16_t BSwap16(uint16_t host_int) {
+#if defined(PROTOBUF_BUILTIN_BSWAP16)
+ return PROTOBUF_BUILTIN_BSWAP16(host_int);
+#elif defined(_MSC_VER)
+ return _byteswap_ushort(host_int);
+#else
+ return (((host_int & uint16_t{0xFF}) << 8) |
+ ((host_int & uint16_t{0xFF00}) >> 8));
+#endif
+}
+
+namespace little_endian {
+
+inline uint16_t FromHost(uint16_t value) {
+#if defined(PROTOBUF_BIG_ENDIAN)
+ return BSwap16(value);
+#else
+ return value;
+#endif
+}
+
+inline uint32_t FromHost(uint32_t value) {
+#if defined(PROTOBUF_BIG_ENDIAN)
+ return BSwap32(value);
+#else
+ return value;
+#endif
+}
+
+inline uint64_t FromHost(uint64_t value) {
+#if defined(PROTOBUF_BIG_ENDIAN)
+ return BSwap64(value);
+#else
+ return value;
+#endif
+}
+
+inline uint16_t ToHost(uint16_t value) {
+#if defined(PROTOBUF_BIG_ENDIAN)
+ return BSwap16(value);
+#else
+ return value;
+#endif
+}
+
+inline uint32_t ToHost(uint32_t value) {
+#if defined(PROTOBUF_BIG_ENDIAN)
+ return BSwap32(value);
+#else
+ return value;
+#endif
+}
+
+inline uint64_t ToHost(uint64_t value) {
+#if defined(PROTOBUF_BIG_ENDIAN)
+ return BSwap64(value);
+#else
+ return value;
+#endif
+}
+
+} // namespace little_endian
+
+namespace big_endian {
+
+inline uint16_t FromHost(uint16_t value) {
+#if defined(PROTOBUF_BIG_ENDIAN)
+ return value;
+#else
+ return BSwap16(value);
+#endif
+}
+
+inline uint32_t FromHost(uint32_t value) {
+#if defined(PROTOBUF_BIG_ENDIAN)
+ return value;
+#else
+ return BSwap32(value);
+#endif
+}
+
+inline uint64_t FromHost(uint64_t value) {
+#if defined(PROTOBUF_BIG_ENDIAN)
+ return value;
+#else
+ return BSwap64(value);
+#endif
+}
+
+inline uint16_t ToHost(uint16_t value) {
+#if defined(PROTOBUF_BIG_ENDIAN)
+ return value;
+#else
+ return BSwap16(value);
+#endif
+}
+
+inline uint32_t ToHost(uint32_t value) {
+#if defined(PROTOBUF_BIG_ENDIAN)
+ return value;
+#else
+ return BSwap32(value);
+#endif
+}
+
+inline uint64_t ToHost(uint64_t value) {
+#if defined(PROTOBUF_BIG_ENDIAN)
+ return value;
+#else
+ return BSwap64(value);
+#endif
+}
+
+} // namespace big_endian
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_ENDIAN_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/explicitly_constructed.h b/toolkit/components/protobuf/src/google/protobuf/explicitly_constructed.h
new file mode 100644
index 0000000000..174c59ab4b
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/explicitly_constructed.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_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, size_t min_align = 1>
+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(min_align > alignof(T) ? min_align
+ : alignof(T)) char space[sizeof(T)];
+ int64_t align_to_int64;
+ void* align_to_ptr;
+ } union_;
+};
+
+// ArenaStringPtr compatible explicitly constructed string type.
+// This empty string type is aligned with a minimum alignment of 8 bytes
+// which is the minimum requirement of ArenaStringPtr
+using ExplicitlyConstructedArenaString = ExplicitlyConstructed<std::string, 8>;
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/extension_set.cc b/toolkit/components/protobuf/src/google/protobuf/extension_set.cc
new file mode 100644
index 0000000000..fada4f5a98
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/extension_set.cc
@@ -0,0 +1,1967 @@
+// 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/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/extension_set_inl.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/metadata_lite.h>
+#include <google/protobuf/parse_context.h>
+#include <google/protobuf/port.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));
+}
+
+// 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
+
+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,
+ LazyEagerVerifyFnType verify_func) {
+ 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,
+ verify_func);
+ 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, nullptr);
+ 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,
+ LazyEagerVerifyFnType verify_func) {
+ GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
+ type == WireFormatLite::TYPE_GROUP);
+ ExtensionInfo info(extendee, number, type, is_repeated, is_packed,
+ verify_func);
+ 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) {
+ // 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.
+ internal::SizedArrayDelete(const_cast<KeyValue*>(flat),
+ sizeof(*flat) * flat_capacity);
+}
+
+// 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, int32_t, Int32)
+PRIMITIVE_ACCESSORS(INT64, int64_t, Int64)
+PRIMITIVE_ACCESSORS(UINT32, uint32_t, UInt32)
+PRIMITIVE_ACCESSORS(UINT64, uint64_t, 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_int32_t_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_int32_t_value =
+ Arena::CreateMessage<RepeatedField<int32_t>>(arena_);
+ break;
+ case WireFormatLite::CPPTYPE_INT64:
+ extension->repeated_int64_t_value =
+ Arena::CreateMessage<RepeatedField<int64_t>>(arena_);
+ break;
+ case WireFormatLite::CPPTYPE_UINT32:
+ extension->repeated_uint32_t_value =
+ Arena::CreateMessage<RepeatedField<uint32_t>>(arena_);
+ break;
+ case WireFormatLite::CPPTYPE_UINT64:
+ extension->repeated_uint64_t_value =
+ Arena::CreateMessage<RepeatedField<uint64_t>>(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<std::string>>(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_int32_t_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_int32_t_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 std::string& ExtensionSet::GetString(
+ int number, const std::string& 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;
+ }
+}
+
+std::string* 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<std::string>(arena_);
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, STRING);
+ }
+ extension->is_cleared = false;
+ return extension->string_value;
+}
+
+const std::string& 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);
+}
+
+std::string* 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);
+}
+
+std::string* 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<std::string>>(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_int32_t_value->RemoveLast();
+ break;
+ case WireFormatLite::CPPTYPE_INT64:
+ extension->repeated_int64_t_value->RemoveLast();
+ break;
+ case WireFormatLite::CPPTYPE_UINT32:
+ extension->repeated_uint32_t_value->RemoveLast();
+ break;
+ case WireFormatLite::CPPTYPE_UINT64:
+ extension->repeated_uint64_t_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_int32_t_value->SwapElements(index1, index2);
+ break;
+ case WireFormatLite::CPPTYPE_INT64:
+ extension->repeated_int64_t_value->SwapElements(index1, index2);
+ break;
+ case WireFormatLite::CPPTYPE_UINT32:
+ extension->repeated_uint32_t_value->SwapElements(index1, index2);
+ break;
+ case WireFormatLite::CPPTYPE_UINT64:
+ extension->repeated_uint64_t_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 an ExtensionSet union without actually constructing the
+// union. Note that we do not count cleared extensions from the source to be
+// part of the total, because there is no need to allocate space for those. We
+// do include cleared extensions in the destination, though, because those are
+// already allocated and will not be going away.
+template <typename ItX, typename ItY>
+size_t SizeOfUnion(ItX it_dest, ItX end_dest, ItY it_source, ItY end_source) {
+ size_t result = 0;
+ while (it_dest != end_dest && it_source != end_source) {
+ if (it_dest->first < it_source->first) {
+ ++result;
+ ++it_dest;
+ } else if (it_dest->first == it_source->first) {
+ ++result;
+ ++it_dest;
+ ++it_source;
+ } else {
+ if (!it_source->second.is_cleared) {
+ ++result;
+ }
+ ++it_source;
+ }
+ }
+ result += std::distance(it_dest, end_dest);
+ for (; it_source != end_source; ++it_source) {
+ if (!it_source->second.is_cleared) {
+ ++result;
+ }
+ }
+ 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, int32_t, RepeatedField<int32_t>);
+ HANDLE_TYPE(INT64, int64_t, RepeatedField<int64_t>);
+ HANDLE_TYPE(UINT32, uint32_t, RepeatedField<uint32_t>);
+ HANDLE_TYPE(UINT64, uint64_t, RepeatedField<uint64_t>);
+ 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<std::string>);
+#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, int32_t, Int32);
+ HANDLE_TYPE(INT64, int64_t, Int64);
+ HANDLE_TYPE(UINT32, uint32_t, UInt32);
+ HANDLE_TYPE(UINT64, uint64_t, 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;
+}
+
+const char* ExtensionSet::ParseField(uint64_t 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<std::string>(), ptr, ctx);
+ }
+ return ParseFieldWithExtensionInfo<std::string>(
+ 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, std::string>(ptr, extendee,
+ metadata, ctx);
+}
+
+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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ 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, int32_t);
+ HANDLE_TYPE(INT64, Int64, int64_t);
+ HANDLE_TYPE(UINT32, UInt32, uint32_t);
+ HANDLE_TYPE(UINT64, UInt64, uint64_t);
+ HANDLE_TYPE(SINT32, SInt32, int32_t);
+ HANDLE_TYPE(SINT64, SInt64, int64_t);
+ 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, uint32_t);
+ HANDLE_TYPE(FIXED64, Fixed64, uint64_t);
+ HANDLE_TYPE(SFIXED32, SFixed32, int32_t);
+ HANDLE_TYPE(SFIXED64, SFixed64, int64_t);
+ 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, int32_t);
+ HANDLE_TYPE(INT64, Int64, int64_t);
+ HANDLE_TYPE(UINT32, UInt32, uint32_t);
+ HANDLE_TYPE(UINT64, UInt64, uint64_t);
+ HANDLE_TYPE(SINT32, SInt32, int32_t);
+ HANDLE_TYPE(SINT64, SInt64, int64_t);
+ 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, uint32_t);
+ HANDLE_TYPE(FIXED64, Fixed64, uint64_t);
+ HANDLE_TYPE(SFIXED32, SFixed32, int32_t);
+ HANDLE_TYPE(SFIXED64, SFixed64, int64_t);
+ 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, int32_t_value);
+ HANDLE_TYPE(INT64, Int64, int64_t_value);
+ HANDLE_TYPE(UINT32, UInt32, uint32_t_value);
+ HANDLE_TYPE(UINT64, UInt64, uint64_t_value);
+ HANDLE_TYPE(SINT32, SInt32, int32_t_value);
+ HANDLE_TYPE(SINT64, SInt64, int64_t_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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ 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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ 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, int32_t);
+ HANDLE_TYPE(INT64, Int64, int64_t);
+ HANDLE_TYPE(UINT32, UInt32, uint32_t);
+ HANDLE_TYPE(UINT64, UInt64, uint64_t);
+ HANDLE_TYPE(SINT32, SInt32, int32_t);
+ HANDLE_TYPE(SINT64, SInt64, int64_t);
+ HANDLE_TYPE(FIXED32, Fixed32, uint32_t);
+ HANDLE_TYPE(FIXED64, Fixed64, uint64_t);
+ HANDLE_TYPE(SFIXED32, SFixed32, int32_t);
+ HANDLE_TYPE(SFIXED64, SFixed64, int64_t);
+ 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, int32_t);
+ HANDLE_TYPE(INT64, Int64, int64_t);
+ HANDLE_TYPE(UINT32, UInt32, uint32_t);
+ HANDLE_TYPE(UINT64, UInt64, uint64_t);
+ HANDLE_TYPE(SINT32, SInt32, int32_t);
+ HANDLE_TYPE(SINT64, SInt64, int64_t);
+ HANDLE_TYPE(FIXED32, Fixed32, uint32_t);
+ HANDLE_TYPE(FIXED64, Fixed64, uint64_t);
+ HANDLE_TYPE(SFIXED32, SFixed32, int32_t);
+ HANDLE_TYPE(SFIXED64, SFixed64, int64_t);
+ 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
+ case WireFormatLite::TYPE_GROUP:
+ for (int i = 0; i < repeated_message_value->size(); i++) {
+ target = stream->EnsureSpace(target);
+ target = WireFormatLite::InternalWriteGroup(
+ number, repeated_message_value->Get(i), target, stream);
+ }
+ break;
+ case WireFormatLite::TYPE_MESSAGE:
+ for (int i = 0; i < repeated_message_value->size(); i++) {
+ auto& msg = repeated_message_value->Get(i);
+ target = WireFormatLite::InternalWriteMessage(
+ number, msg, msg.GetCachedSize(), target, stream);
+ }
+ break;
+ }
+ }
+ } 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, int32_t_value);
+ HANDLE_TYPE(INT64, Int64, int64_t_value);
+ HANDLE_TYPE(UINT32, UInt32, uint32_t_value);
+ HANDLE_TYPE(UINT64, UInt64, uint64_t_value);
+ HANDLE_TYPE(SINT32, SInt32, int32_t_value);
+ HANDLE_TYPE(SINT64, SInt64, int64_t_value);
+ HANDLE_TYPE(FIXED32, Fixed32, uint32_t_value);
+ HANDLE_TYPE(FIXED64, Fixed64, uint64_t_value);
+ HANDLE_TYPE(SFIXED32, SFixed32, int32_t_value);
+ HANDLE_TYPE(SFIXED64, SFixed64, int64_t_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 = WireFormatLite::InternalWriteMessage(
+ number, *message_value, message_value->GetCachedSize(), 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,
+ message_value->GetCachedSize(), 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;
+}
+
+LazyEagerVerifyFnType FindExtensionLazyEagerVerifyFn(
+ const MessageLite* extendee, int number) {
+ const ExtensionInfo* registered = FindRegisteredExtension(extendee, number);
+ if (registered != nullptr) {
+ return registered->lazy_eager_verify_func;
+ }
+ return nullptr;
+}
+
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
diff --git a/toolkit/components/protobuf/src/google/protobuf/extension_set.h b/toolkit/components/protobuf/src/google/protobuf/extension_set.h
new file mode 100644
index 0000000000..0e6d052110
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/extension_set.h
@@ -0,0 +1,1561 @@
+// 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/io/coded_stream.h>
+#include <google/protobuf/port.h>
+#include <google/protobuf/parse_context.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
+enum class LazyVerifyOption;
+} // 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,
+ LazyEagerVerifyFnType verify_func)
+ : message(extendee),
+ number(param_number),
+ type(type_param),
+ is_repeated(isrepeated),
+ is_packed(ispacked),
+ enum_validity_check(),
+ lazy_eager_verify_func(verify_func) {}
+
+ 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;
+
+ // If this field is potentially lazy this function can be used as a cheap
+ // verification of the raw bytes.
+ // If nullptr then no verification is performed.
+ LazyEagerVerifyFnType lazy_eager_verify_func = nullptr;
+};
+
+// An ExtensionFinder is an object which looks up extension definitions. It
+// must implement this method:
+//
+// bool Find(int number, ExtensionInfo* output);
+
+// GeneratedExtensionFinder is an ExtensionFinder which finds extensions
+// defined in .proto files which have been compiled into the binary.
+class PROTOBUF_EXPORT GeneratedExtensionFinder {
+ public:
+ explicit GeneratedExtensionFinder(const MessageLite* extendee)
+ : extendee_(extendee) {}
+
+ // Returns true and fills in *output if found, otherwise returns false.
+ bool Find(int number, ExtensionInfo* output);
+
+ private:
+ const MessageLite* extendee_;
+};
+
+// 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(ArenaInitialized, Arena* arena) : ExtensionSet(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,
+ LazyEagerVerifyFnType verify_func);
+ 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,
+ LazyEagerVerifyFnType verify_func);
+
+ // =================================================================
+
+ // 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 -------------------------------------------------
+
+ int32_t GetInt32(int number, int32_t default_value) const;
+ int64_t GetInt64(int number, int64_t default_value) const;
+ uint32_t GetUInt32(int number, uint32_t default_value) const;
+ uint64_t GetUInt64(int number, uint64_t 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 std::string& GetString(int number,
+ const std::string& 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, int32_t value, desc);
+ void SetInt64(int number, FieldType type, int64_t value, desc);
+ void SetUInt32(int number, FieldType type, uint32_t value, desc);
+ void SetUInt64(int number, FieldType type, uint64_t 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, std::string value, desc);
+ std::string* 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);
+
+ int32_t GetRepeatedInt32(int number, int index) const;
+ int64_t GetRepeatedInt64(int number, int index) const;
+ uint32_t GetRepeatedUInt32(int number, int index) const;
+ uint64_t 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 std::string& GetRepeatedString(int number, int index) const;
+ const MessageLite& GetRepeatedMessage(int number, int index) const;
+
+ void SetRepeatedInt32(int number, int index, int32_t value);
+ void SetRepeatedInt64(int number, int index, int64_t value);
+ void SetRepeatedUInt32(int number, int index, uint32_t value);
+ void SetRepeatedUInt64(int number, int index, uint64_t 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, std::string value);
+ std::string* 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, int32_t value, desc);
+ void AddInt64(int number, FieldType type, bool packed, int64_t value, desc);
+ void AddUInt32(int number, FieldType type, bool packed, uint32_t value, desc);
+ void AddUInt64(int number, FieldType type, bool packed, uint64_t 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, std::string value, desc);
+ std::string* 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);
+
+ // =================================================================
+ // 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;
+
+ // Lite parser
+ const char* ParseField(uint64_t tag, const char* ptr,
+ const MessageLite* extendee,
+ internal::InternalMetadata* metadata,
+ internal::ParseContext* ctx);
+ // Full parser
+ const char* ParseField(uint64_t 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)) {
+ uint32_t 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;
+ }
+
+ // 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 int32_t& GetRefInt32(int number, const int32_t& default_value) const;
+ const int64_t& GetRefInt64(int number, const int64_t& default_value) const;
+ const uint32_t& GetRefUInt32(int number, const uint32_t& default_value) const;
+ const uint64_t& GetRefUInt64(int number, const uint64_t& 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 int32_t& GetRefRepeatedInt32(int number, int index) const;
+ const int64_t& GetRefRepeatedInt64(int number, int index) const;
+ const uint32_t& GetRefRepeatedUInt32(int number, int index) const;
+ const uint64_t& 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 const char* _InternalParse(const Message& prototype, Arena* arena,
+ LazyVerifyOption option, 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 {
+ int32_t int32_t_value;
+ int64_t int64_t_value;
+ uint32_t uint32_t_value;
+ uint64_t uint64_t_value;
+ float float_value;
+ double double_value;
+ bool bool_value;
+ int enum_value;
+ std::string* string_value;
+ MessageLite* message_value;
+ LazyMessageExtension* lazymessage_value;
+
+ RepeatedField<int32_t>* repeated_int32_t_value;
+ RepeatedField<int64_t>* repeated_int64_t_value;
+ RepeatedField<uint32_t>* repeated_uint32_t_value;
+ RepeatedField<uint64_t>* repeated_uint64_t_value;
+ RepeatedField<float>* repeated_float_value;
+ RepeatedField<double>* repeated_double_value;
+ RepeatedField<bool>* repeated_bool_value;
+ RepeatedField<int>* repeated_enum_value;
+ RepeatedPtrField<std::string>* 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);
+
+ inline static 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.
+ }
+ PROTOBUF_ASSUME(false); // switch handles all possible enum values
+ return false;
+ }
+
+ // 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).
+ template <typename ExtensionFinder>
+ bool FindExtensionInfoFromTag(uint32_t 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);
+ }
+
+ // 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).
+ template <typename ExtensionFinder>
+ bool 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;
+ }
+
+ GOOGLE_DCHECK(extension->type > 0 &&
+ extension->type <= WireFormatLite::MAX_FIELD_TYPE);
+ auto real_type = static_cast<WireFormatLite::FieldType>(extension->type);
+
+ WireFormatLite::WireType expected_wire_type =
+ WireFormatLite::WireTypeForFieldType(real_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;
+ }
+
+ // 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;
+
+ // 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);
+
+ bool FindExtension(int wire_type, uint32_t 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, uint32_t field,
+ const Message* extendee,
+ const internal::ParseContext* ctx,
+ ExtensionInfo* extension, bool* was_packed_on_wire);
+ // Used for MessageSet only
+ const char* ParseFieldMaybeLazily(uint64_t 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(uint64_t 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,
+ std::string value,
+ const FieldDescriptor* descriptor) {
+ MutableString(number, type, descriptor)->assign(std::move(value));
+}
+inline void ExtensionSet::SetRepeatedString(int number, int index,
+ std::string value) {
+ MutableRepeatedString(number, index)->assign(std::move(value));
+}
+inline void ExtensionSet::AddString(int number, FieldType type,
+ std::string 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<int32_t> 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,
+ LazyEagerVerifyFnType verify_func) {
+ ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number,
+ type, false, is_packed, verify_func);
+ }
+};
+
+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,
+ LazyEagerVerifyFnType verify_func) {
+ ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number,
+ type, true, is_packed, verify_func);
+ }
+};
+
+class PROTOBUF_EXPORT RepeatedPrimitiveDefaults {
+ private:
+ template <typename Type>
+ friend class RepeatedPrimitiveTypeTraits;
+ static const RepeatedPrimitiveDefaults* default_instance();
+ RepeatedField<int32_t> default_repeated_field_int32_t_;
+ RepeatedField<int64_t> default_repeated_field_int64_t_;
+ RepeatedField<uint32_t> default_repeated_field_uint32_t_;
+ RepeatedField<uint64_t> default_repeated_field_uint64_t_;
+ 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(int32_t, Int32)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(int64_t, Int64)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32_t, UInt32)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64_t, 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 std::string& ConstType;
+ typedef std::string* MutableType;
+ typedef StringTypeTraits Singular;
+
+ static inline const std::string& Get(int number, const ExtensionSet& set,
+ ConstType default_value) {
+ return set.GetString(number, default_value);
+ }
+ static inline const std::string* 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 std::string& value, ExtensionSet* set) {
+ set->SetString(number, field_type, value, nullptr);
+ }
+ static inline std::string* 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,
+ LazyEagerVerifyFnType verify_func) {
+ ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number,
+ type, false, is_packed, verify_func);
+ }
+};
+
+class PROTOBUF_EXPORT RepeatedStringTypeTraits {
+ public:
+ typedef const std::string& ConstType;
+ typedef std::string* MutableType;
+ typedef RepeatedStringTypeTraits Repeated;
+
+ typedef RepeatedPtrField<std::string> RepeatedFieldType;
+
+ static inline const std::string& Get(int number, const ExtensionSet& set,
+ int index) {
+ return set.GetRepeatedString(number, index);
+ }
+ static inline const std::string* GetPtr(int number, const ExtensionSet& set,
+ int index) {
+ return &Get(number, set, index);
+ }
+ static inline const RepeatedPtrField<std::string>* GetRepeatedPtr(
+ int number, const ExtensionSet& set) {
+ return &GetRepeated(number, set);
+ }
+ static inline void Set(int number, int index, const std::string& value,
+ ExtensionSet* set) {
+ set->SetRepeatedString(number, index, value);
+ }
+ static inline std::string* 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 std::string& value, ExtensionSet* set) {
+ set->AddString(number, field_type, value, nullptr);
+ }
+ static inline std::string* Add(int number, FieldType field_type,
+ ExtensionSet* set) {
+ return set->AddString(number, field_type, nullptr);
+ }
+ static inline const RepeatedPtrField<std::string>& GetRepeated(
+ int number, const ExtensionSet& set) {
+ return *reinterpret_cast<const RepeatedPtrField<std::string>*>(
+ set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
+ }
+
+ static inline RepeatedPtrField<std::string>* MutableRepeated(
+ int number, FieldType field_type, bool is_packed, ExtensionSet* set) {
+ return reinterpret_cast<RepeatedPtrField<std::string>*>(
+ 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,
+ LazyEagerVerifyFnType fn) {
+ ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number,
+ type, true, is_packed, fn);
+ }
+
+ 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,
+ LazyEagerVerifyFnType fn) {
+ 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
+ // int32_t's default repeated field object.
+ return reinterpret_cast<const RepeatedField<Type>*>(
+ RepeatedPrimitiveTypeTraits<int32_t>::GetDefaultRepeatedField());
+ }
+ template <typename ExtendeeT>
+ static void Register(int number, FieldType type, bool is_packed,
+ LazyEagerVerifyFnType fn) {
+ 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,
+ LazyEagerVerifyFnType fn) {
+ ExtensionSet::RegisterMessageExtension(&ExtendeeT::default_instance(),
+ number, type, false, is_packed,
+ &Type::default_instance(), fn);
+ }
+};
+
+// Used by WireFormatVerify to extract the verify function from the registry.
+LazyEagerVerifyFnType FindExtensionLazyEagerVerifyFn(
+ const MessageLite* extendee, int number);
+
+// 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,
+ LazyEagerVerifyFnType fn) {
+ ExtensionSet::RegisterMessageExtension(&ExtendeeT::default_instance(),
+ number, type, true, is_packed,
+ &Type::default_instance(), fn);
+ }
+};
+
+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<int32_t>, 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,
+ LazyEagerVerifyFnType verify_func = nullptr)
+ : number_(number), default_value_(default_value) {
+ Register(number, verify_func);
+ }
+ inline int number() const { return number_; }
+ typename TypeTraits::ConstType default_value() const {
+ return default_value_;
+ }
+
+ static void Register(int number, LazyEagerVerifyFnType verify_func) {
+ TypeTraits::template Register<ExtendeeType>(number, field_type, is_packed,
+ verify_func);
+ }
+
+ 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/toolkit/components/protobuf/src/google/protobuf/extension_set_heavy.cc b/toolkit/components/protobuf/src/google/protobuf/extension_set_heavy.cc
new file mode 100644
index 0000000000..a4bb94860c
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/extension_set_heavy.cc
@@ -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.
+//
+// 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/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/extension_set_inl.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/parse_context.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>
+
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// 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:
+ DescriptorPoolExtensionFinder(const DescriptorPool* pool,
+ MessageFactory* factory,
+ const Descriptor* containing_type)
+ : pool_(pool), factory_(factory), containing_type_(containing_type) {}
+
+ bool Find(int number, ExtensionInfo* output);
+
+ 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, uint32_t 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(uint64_t 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(
+ uint64_t 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);
+}
+
+int ExtensionSet::SpaceUsedExcludingSelf() const {
+ return internal::FromIntSize(SpaceUsedExcludingSelfLong());
+}
+
+size_t ExtensionSet::SpaceUsedExcludingSelfLong() const {
+ size_t total_size =
+ (is_large() ? map_.large->size() : flat_capacity_) * 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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ 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);
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
diff --git a/toolkit/components/protobuf/src/google/protobuf/extension_set_inl.h b/toolkit/components/protobuf/src/google/protobuf/extension_set_inl.h
new file mode 100644
index 0000000000..e4e711721d
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/extension_set_inl.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.
+
+#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
+#define GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
+
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/metadata_lite.h>
+#include <google/protobuf/parse_context.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: { \
+ uint64_t 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: { \
+ uint64_t 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, uint32_t);
+ HANDLE_FIXED_TYPE(FIXED64, UInt64, uint64_t);
+ HANDLE_FIXED_TYPE(SFIXED32, Int32, int32_t);
+ HANDLE_FIXED_TYPE(SFIXED64, Int64, int64_t);
+ HANDLE_FIXED_TYPE(FLOAT, Float, float);
+ HANDLE_FIXED_TYPE(DOUBLE, Double, double);
+#undef HANDLE_FIXED_TYPE
+
+ case WireFormatLite::TYPE_ENUM: {
+ uint64_t 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: {
+ std::string* 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);
+ uint32_t 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) {
+ std::string payload;
+ uint32_t type_id;
+ enum class State { kNoTag, kHasType, kHasPayload, kDone };
+ State state = State::kNoTag;
+
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag = static_cast<uint8_t>(*ptr++);
+ if (tag == WireFormatLite::kMessageSetTypeIdTag) {
+ uint64_t tmp;
+ ptr = ParseBigVarint(ptr, &tmp);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ if (state == State::kNoTag) {
+ type_id = tmp;
+ state = State::kHasType;
+ } else if (state == State::kHasPayload) {
+ type_id = tmp;
+ 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());
+ }
+ state = State::kDone;
+ }
+ } else if (tag == WireFormatLite::kMessageSetMessageTag) {
+ if (state == State::kHasType) {
+ ptr = ParseFieldMaybeLazily(static_cast<uint64_t>(type_id) * 8 + 2, ptr,
+ extendee, metadata, ctx);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+ state = State::kDone;
+ } else {
+ std::string tmp;
+ int32_t size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ ptr = ctx->ReadString(ptr, size, &tmp);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ if (state == State::kNoTag) {
+ payload = std::move(tmp);
+ state = State::kHasPayload;
+ }
+ }
+ } 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/toolkit/components/protobuf/src/google/protobuf/field_access_listener.h b/toolkit/components/protobuf/src/google/protobuf/field_access_listener.h
new file mode 100644
index 0000000000..47422e63c1
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/field_access_listener.h
@@ -0,0 +1,172 @@
+// 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_FIELD_ACCESS_LISTENER_H__
+#define GOOGLE_PROTOBUF_FIELD_ACCESS_LISTENER_H__
+
+#include <cstddef>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/message_lite.h>
+
+
+namespace google {
+namespace protobuf {
+
+// A default/no-op implementation of message hooks.
+//
+// See go/statically-dispatched-message-hooks for details.
+template <typename Proto>
+struct NoOpAccessListener {
+ // Number of fields are provided at compile time for the trackers to be able
+ // to have stack allocated bitmaps for the fields. This is useful for
+ // performance critical trackers. This is also to avoid cyclic dependencies
+ // if the number of fields is needed.
+ static constexpr int kFields = Proto::_kInternalFieldNumber;
+ // Default constructor is called during the static global initialization of
+ // the program.
+ // We provide a pointer to extract the name of the proto not to get cyclic
+ // dependencies on GetDescriptor() and OnGetMetadata() calls. If you want
+ // to differentiate the protos during the runtime before the start of the
+ // program, use this functor to get its name. We either way need it for
+ // LITE_RUNTIME protos as they don't have descriptors at all.
+ explicit NoOpAccessListener(StringPiece (*name_extractor)()) {}
+ // called repeatedly during serialization/deserialization/ByteSize of
+ // Reflection as:
+ // AccessListener<MessageT>::OnSerialize(this);
+ static void OnSerialize(const MessageLite* msg) {}
+ static void OnDeserialize(const MessageLite* msg) {}
+ static void OnByteSize(const MessageLite* msg) {}
+ static void OnMergeFrom(const MessageLite* to, const MessageLite* from) {}
+
+ // NOTE: This function can be called pre-main. Make sure it does not make
+ // the state of the listener invalid.
+ static void OnGetMetadata() {}
+
+ // called from accessors as:
+ // AccessListener<MessageT>::On$operation(this, &field_storage_);
+ // If you need to override this with type, in your hook implementation
+ // introduce
+ // template <int kFieldNum, typename T>
+ // static void On$operation(const MessageLite* msg,
+ // const T* field) {}
+ // And overloads for std::nullptr_t for incomplete types such as Messages,
+ // Maps. Extract them using reflection if you need. Consequently, second
+ // argument can be null pointer.
+ // For an example, see proto_hooks/testing/memory_test_field_listener.h
+ // And argument template deduction will deduce the type itself without
+ // changing the generated code.
+
+ // add_<field>(f)
+ template <int kFieldNum>
+ static void OnAdd(const MessageLite* msg, const void* field) {}
+
+ // add_<field>()
+ template <int kFieldNum>
+ static void OnAddMutable(const MessageLite* msg, const void* field) {}
+
+ // <field>() and <repeated_field>(i)
+ template <int kFieldNum>
+ static void OnGet(const MessageLite* msg, const void* field) {}
+
+ // clear_<field>()
+ template <int kFieldNum>
+ static void OnClear(const MessageLite* msg, const void* field) {}
+
+ // has_<field>()
+ template <int kFieldNum>
+ static void OnHas(const MessageLite* msg, const void* field) {}
+
+ // <repeated_field>()
+ template <int kFieldNum>
+ static void OnList(const MessageLite* msg, const void* field) {}
+
+ // mutable_<field>()
+ template <int kFieldNum>
+ static void OnMutable(const MessageLite* msg, const void* field) {}
+
+ // mutable_<repeated_field>()
+ template <int kFieldNum>
+ static void OnMutableList(const MessageLite* msg, const void* field) {}
+
+ // release_<field>()
+ template <int kFieldNum>
+ static void OnRelease(const MessageLite* msg, const void* field) {}
+
+ // set_<field>() and set_<repeated_field>(i)
+ template <int kFieldNum>
+ static void OnSet(const MessageLite* msg, const void* field) {}
+
+ // <repeated_field>_size()
+ template <int kFieldNum>
+ static void OnSize(const MessageLite* msg, const void* field) {}
+
+ static void OnHasExtension(const MessageLite* msg, int extension_tag,
+ const void* field) {}
+ // TODO(b/190614678): Support clear in the proto compiler.
+ static void OnClearExtension(const MessageLite* msg, int extension_tag,
+ const void* field) {}
+ static void OnExtensionSize(const MessageLite* msg, int extension_tag,
+ const void* field) {}
+ static void OnGetExtension(const MessageLite* msg, int extension_tag,
+ const void* field) {}
+ static void OnMutableExtension(const MessageLite* msg, int extension_tag,
+ const void* field) {}
+ static void OnSetExtension(const MessageLite* msg, int extension_tag,
+ const void* field) {}
+ static void OnReleaseExtension(const MessageLite* msg, int extension_tag,
+ const void* field) {}
+ static void OnAddExtension(const MessageLite* msg, int extension_tag,
+ const void* field) {}
+ static void OnAddMutableExtension(const MessageLite* msg, int extension_tag,
+ const void* field) {}
+ static void OnListExtension(const MessageLite* msg, int extension_tag,
+ const void* field) {}
+ static void OnMutableListExtension(const MessageLite* msg, int extension_tag,
+ const void* field) {}
+};
+
+} // namespace protobuf
+} // namespace google
+
+#ifndef REPLACE_PROTO_LISTENER_IMPL
+namespace google {
+namespace protobuf {
+template <class T>
+using AccessListener = NoOpAccessListener<T>;
+} // namespace protobuf
+} // namespace google
+#else
+// You can put your implementations of hooks/listeners here.
+// All hooks are subject to approval by protobuf-team@.
+
+#endif // !REPLACE_PROTO_LISTENER_IMPL
+
+#endif // GOOGLE_PROTOBUF_FIELD_ACCESS_LISTENER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/field_mask.pb.cc b/toolkit/components/protobuf/src/google/protobuf/field_mask.pb.cc
new file mode 100644
index 0000000000..7860bfbfed
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/field_mask.pb.cc
@@ -0,0 +1,284 @@
+// 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
+
+namespace _pb = ::PROTOBUF_NAMESPACE_ID;
+namespace _pbi = _pb::internal;
+
+PROTOBUF_NAMESPACE_OPEN
+PROTOBUF_CONSTEXPR FieldMask::FieldMask(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.paths_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct FieldMaskDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR FieldMaskDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~FieldMaskDefaultTypeInternal() {}
+ union {
+ FieldMask _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FieldMaskDefaultTypeInternal _FieldMask_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto[1];
+static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr;
+static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr;
+
+const uint32_t 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, _impl_.paths_),
+};
+static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FieldMask)},
+};
+
+static const ::_pb::Message* const file_default_instances[] = {
+ &::PROTOBUF_NAMESPACE_ID::_FieldMask_default_instance_._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 ::_pbi::once_flag descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_once;
+const ::_pbi::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 ::_pbi::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_PRIORITY2 static ::_pbi::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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldMask)
+}
+FieldMask::FieldMask(const FieldMask& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ FieldMask* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.paths_){from._impl_.paths_}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldMask)
+}
+
+inline void FieldMask::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.paths_){arena}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+FieldMask::~FieldMask() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FieldMask)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void FieldMask::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.paths_.~RepeatedPtrField();
+}
+
+void FieldMask::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void FieldMask::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldMask)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.paths_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FieldMask::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.FieldMask.paths"));
+ 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)
+ uint32_t 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 = ::_pbi::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;
+
+ uint32_t 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(_impl_.paths_.size());
+ for (int i = 0, n = _impl_.paths_.size(); i < n; i++) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ _impl_.paths_.Get(i));
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldMask::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ FieldMask::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldMask::GetClassData() const { return &_class_data_; }
+
+
+void FieldMask::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<FieldMask*>(&to_msg);
+ auto& from = static_cast<const FieldMask&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldMask)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.paths_.MergeFrom(from._impl_.paths_);
+ _this->_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_);
+ _impl_.paths_.InternalSwap(&other->_impl_.paths_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FieldMask::GetMetadata() const {
+ return ::_pbi::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/toolkit/components/protobuf/src/google/protobuf/field_mask.pb.h b/toolkit/components/protobuf/src/google/protobuf/field_mask.pb.h
new file mode 100644
index 0000000000..ecc6edee9a
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/field_mask.pb.h
@@ -0,0 +1,317 @@
+// 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 < 3021000
+#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 3021006 < 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_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 uint32_t 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 PROTOBUF_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) {
+ FieldMask::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& paths(int index) const;
+ std::string* mutable_paths(int index);
+ void set_paths(int index, const std::string& value);
+ void set_paths(int index, std::string&& value);
+ void set_paths(int index, const char* value);
+ void set_paths(int index, const char* value, size_t size);
+ std::string* add_paths();
+ void add_paths(const std::string& value);
+ void add_paths(std::string&& value);
+ void add_paths(const char* value);
+ void add_paths(const char* value, size_t size);
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& paths() const;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_paths();
+ private:
+ const std::string& _internal_paths(int index) const;
+ std::string* _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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> paths_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 _impl_.paths_.size();
+}
+inline int FieldMask::paths_size() const {
+ return _internal_paths_size();
+}
+inline void FieldMask::clear_paths() {
+ _impl_.paths_.Clear();
+}
+inline std::string* FieldMask::add_paths() {
+ std::string* _s = _internal_add_paths();
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.FieldMask.paths)
+ return _s;
+}
+inline const std::string& FieldMask::_internal_paths(int index) const {
+ return _impl_.paths_.Get(index);
+}
+inline const std::string& FieldMask::paths(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldMask.paths)
+ return _internal_paths(index);
+}
+inline std::string* FieldMask::mutable_paths(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldMask.paths)
+ return _impl_.paths_.Mutable(index);
+}
+inline void FieldMask::set_paths(int index, const std::string& value) {
+ _impl_.paths_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
+}
+inline void FieldMask::set_paths(int index, std::string&& value) {
+ _impl_.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);
+ _impl_.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) {
+ _impl_.paths_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldMask.paths)
+}
+inline std::string* FieldMask::_internal_add_paths() {
+ return _impl_.paths_.Add();
+}
+inline void FieldMask::add_paths(const std::string& value) {
+ _impl_.paths_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths)
+}
+inline void FieldMask::add_paths(std::string&& value) {
+ _impl_.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);
+ _impl_.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) {
+ _impl_.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<std::string>&
+FieldMask::paths() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FieldMask.paths)
+ return _impl_.paths_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
+FieldMask::mutable_paths() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldMask.paths)
+ return &_impl_.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/toolkit/components/protobuf/src/google/protobuf/field_mask.proto b/toolkit/components/protobuf/src/google/protobuf/field_mask.proto
new file mode 100644
index 0000000000..6b5104f188
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/generated_enum_reflection.h b/toolkit/components/protobuf/src/google/protobuf/generated_enum_reflection.h
new file mode 100644
index 0000000000..b96a9c61f9
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/generated_enum_reflection.h
@@ -0,0 +1,100 @@
+// 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/port.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/generated_enum_util.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+// Must be included last.
+#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 std::string& 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/toolkit/components/protobuf/src/google/protobuf/generated_enum_util.cc b/toolkit/components/protobuf/src/google/protobuf/generated_enum_util.cc
new file mode 100644
index 0000000000..df7583e999
--- /dev/null
+++ b/toolkit/components/protobuf/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<std::string>* 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/toolkit/components/protobuf/src/google/protobuf/generated_enum_util.h b/toolkit/components/protobuf/src/google/protobuf/generated_enum_util.h
new file mode 100644
index 0000000000..5d10ac010e
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/generated_enum_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.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
+#define GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
+
+
+#include <type_traits>
+
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/message_lite.h>
+
+// Must be included last.
+#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 std::string form.
+PROTOBUF_EXPORT bool InitializeEnumStrings(
+ const EnumEntry* enums, const int* sorted_indices, size_t size,
+ internal::ExplicitlyConstructed<std::string>* enum_strings);
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/generated_message_bases.cc b/toolkit/components/protobuf/src/google/protobuf/generated_message_bases.cc
new file mode 100644
index 0000000000..306a38eef3
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/generated_message_bases.cc
@@ -0,0 +1,124 @@
+// 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/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/parse_context.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() {
+ (void)_internal_metadata_.DeleteReturnArena<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)) {
+ uint32_t 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/toolkit/components/protobuf/src/google/protobuf/generated_message_bases.h b/toolkit/components/protobuf/src/google/protobuf/generated_message_bases.h
new file mode 100644
index 0000000000..b295218a70
--- /dev/null
+++ b/toolkit/components/protobuf/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/io/zero_copy_stream_impl.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/parse_context.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/toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.cc b/toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.cc
new file mode 100644
index 0000000000..2a807e066b
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.cc
@@ -0,0 +1,3168 @@
+// 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/stubs/mutex.h>
+#include <google/protobuf/stubs/casts.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.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/repeated_field.h>
+#include <google/protobuf/unknown_field_set.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 std::string& 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 {
+ if (field->options().unverified_lazy()) return true;
+
+ // Message fields with [lazy=true] will be eagerly verified
+ // (go/verified-lazy).
+ return field->options().lazy() && !IsEagerlyVerifiedLazyField(field);
+}
+
+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 this message owns an arena, add any unused space that's been allocated.
+ auto* arena = Arena::InternalGetArenaForAllocation(&message);
+ if (arena != nullptr && Arena::InternalGetOwningArena(&message) == nullptr &&
+ arena->InternalIsMessageOwnedArena()) {
+ total_size += arena->SpaceAllocated() - arena->SpaceUsed();
+ }
+
+ 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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ 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<std::string> >(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 std::string* ptr =
+ &GetField<InlinedStringField>(message, field).GetNoArena();
+ total_size += StringSpaceUsedExcludingSelfLong(*ptr);
+ } else {
+ // 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.
+ const auto& str = GetField<ArenaStringPtr>(message, field);
+ if (!str.IsDefault() || schema_.InRealOneof(field)) {
+ // string fields are represented by just a pointer, so also
+ // include sizeof(string) as well.
+ total_size += sizeof(std::string) +
+ StringSpaceUsedExcludingSelfLong(str.Get());
+ }
+ }
+ 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(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);
+
+ static void SwapNonMessageNonStringField(const Reflection* r, Message* lhs,
+ Message* rhs,
+ const FieldDescriptor* field);
+};
+
+template <bool unsafe_shallow_swap>
+void SwapFieldHelper::SwapRepeatedStringField(const Reflection* r, Message* lhs,
+ Message* rhs,
+ const FieldDescriptor* field) {
+ switch (field->options().ctype()) {
+ default:
+ case FieldOptions::STRING: {
+ auto* lhs_string = r->MutableRaw<RepeatedPtrFieldBase>(lhs, field);
+ auto* rhs_string = r->MutableRaw<RepeatedPtrFieldBase>(rhs, field);
+ if (unsafe_shallow_swap) {
+ lhs_string->InternalSwap(rhs_string);
+ } else {
+ lhs_string->Swap<GenericTypeHandler<std::string>>(rhs_string);
+ }
+ break;
+ }
+ }
+}
+
+template <bool unsafe_shallow_swap>
+void SwapFieldHelper::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);
+ uint32_t index = r->schema_.InlinedStringIndex(field);
+ GOOGLE_DCHECK_GT(index, 0);
+ uint32_t* lhs_array = r->MutableInlinedStringDonatedArray(lhs);
+ uint32_t* rhs_array = r->MutableInlinedStringDonatedArray(rhs);
+ uint32_t* lhs_state = &lhs_array[index / 32];
+ uint32_t* rhs_state = &rhs_array[index / 32];
+ bool lhs_arena_dtor_registered = (lhs_array[0] & 0x1u) == 0;
+ bool rhs_arena_dtor_registered = (rhs_array[0] & 0x1u) == 0;
+ const uint32_t mask = ~(static_cast<uint32_t>(1) << (index % 32));
+ if (unsafe_shallow_swap || lhs_arena == rhs_arena) {
+ InlinedStringField::InternalSwap(lhs_string, lhs_arena,
+ lhs_arena_dtor_registered, lhs, rhs_string,
+ rhs_arena, rhs_arena_dtor_registered, rhs);
+ } else {
+ const std::string temp = lhs_string->Get();
+ lhs_string->Set(rhs_string->Get(), lhs_arena,
+ r->IsInlinedStringDonated(*lhs, field), lhs_state, mask,
+ lhs);
+ rhs_string->Set(temp, rhs_arena, r->IsInlinedStringDonated(*rhs, field),
+ rhs_state, mask, rhs);
+ }
+}
+
+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(
+ 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(ArenaStringPtr* lhs, Arena* lhs_arena,
+ ArenaStringPtr* rhs,
+ Arena* rhs_arena) {
+ if (lhs_arena == rhs_arena) {
+ ArenaStringPtr::InternalSwap(lhs, lhs_arena, rhs, rhs_arena);
+ } else if (lhs->IsDefault() && rhs->IsDefault()) {
+ // Nothing to do.
+ } else if (lhs->IsDefault()) {
+ lhs->Set(rhs->Get(), lhs_arena);
+ // rhs needs to be destroyed before overwritten.
+ rhs->Destroy();
+ rhs->InitDefault();
+ } else if (rhs->IsDefault()) {
+ rhs->Set(lhs->Get(), rhs_arena);
+ // lhs needs to be destroyed before overwritten.
+ lhs->Destroy();
+ lhs->InitDefault();
+ } else {
+ std::string temp = lhs->Get();
+ lhs->Set(rhs->Get(), lhs_arena);
+ rhs->Set(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);
+ }
+}
+
+void SwapFieldHelper::SwapNonMessageNonStringField(
+ const Reflection* r, Message* lhs, Message* rhs,
+ const FieldDescriptor* field) {
+ switch (field->cpp_type()) {
+#define SWAP_VALUES(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ std::swap(*r->MutableRaw<TYPE>(lhs, field), \
+ *r->MutableRaw<TYPE>(rhs, field)); \
+ break;
+
+ SWAP_VALUES(INT32, int32_t);
+ SWAP_VALUES(INT64, int64_t);
+ SWAP_VALUES(UINT32, uint32_t);
+ SWAP_VALUES(UINT64, uint64_t);
+ SWAP_VALUES(FLOAT, float);
+ SWAP_VALUES(DOUBLE, double);
+ SWAP_VALUES(BOOL, bool);
+ SWAP_VALUES(ENUM, int);
+#undef SWAP_VALUES
+ default:
+ GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
+ }
+}
+
+} // 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, int32_t);
+ SWAP_ARRAYS(INT64, int64_t);
+ SWAP_ARRAYS(UINT32, uint32_t);
+ SWAP_ARRAYS(UINT64, uint64_t);
+ 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()) {
+ 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:
+ internal::SwapFieldHelper::SwapNonMessageNonStringField(
+ this, message1, message2, field);
+ }
+ }
+}
+
+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 {
+ internal::SwapFieldHelper::SwapNonMessageNonStringField(this, message1,
+ message2, field);
+ }
+ return;
+ }
+
+ switch (field->cpp_type()) {
+#define SHALLOW_SWAP_ARRAYS(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ MutableRaw<RepeatedField<TYPE>>(message1, field) \
+ ->InternalSwap(MutableRaw<RepeatedField<TYPE>>(message2, field)); \
+ break;
+
+ SHALLOW_SWAP_ARRAYS(INT32, int32_t);
+ SHALLOW_SWAP_ARRAYS(INT64, int64_t);
+ SHALLOW_SWAP_ARRAYS(UINT32, uint32_t);
+ SHALLOW_SWAP_ARRAYS(UINT64, uint64_t);
+ 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(int32_t, int32, Int32);
+ LOCAL_VAR_ACCESSOR(int64_t, int64, Int64);
+ LOCAL_VAR_ACCESSOR(uint32_t, uint32, Uint32);
+ LOCAL_VAR_ACCESSOR(uint64_t, 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 std::string& GetString() const { return string_val; }
+ void SetString(const std::string& v) { string_val = v; }
+ Message* UnsafeGetMessage() const { return GetMessage(); }
+ void UnsafeSetMessage(Message* v) { SetMessage(v); }
+ void ClearOneofCase() {}
+
+ union {
+ int32_t type_int32;
+ int64_t type_int64;
+ uint32_t type_uint32;
+ uint64_t 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;
+
+ // std::string cannot be in union.
+ std::string 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(int32_t, int32, Int32);
+ MESSAGE_FIELD_ACCESSOR(int64_t, int64, Int64);
+ MESSAGE_FIELD_ACCESSOR(uint32_t, uint32, Uint32);
+ MESSAGE_FIELD_ACCESSOR(uint64_t, 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);
+ std::string GetString() const {
+ return reflection->GetString(*message, field);
+ }
+ void SetString(const std::string& 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_t oneof_case_lhs = GetOneofCase(*lhs, oneof_descriptor);
+ uint32_t 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);
+ if (field->options().ctype() == FieldOptions::STRING &&
+ IsInlined(field)) {
+ GOOGLE_DCHECK(!unsafe_shallow_swap ||
+ message1->GetArenaForAllocation() ==
+ message2->GetArenaForAllocation());
+ SwapInlinedStringDonated(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_t* lhs_has_bits = MutableHasBits(lhs);
+ uint32_t* 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_.HasInlinedString()) {
+ uint32_t* lhs_donated_array = MutableInlinedStringDonatedArray(lhs);
+ uint32_t* rhs_donated_array = MutableInlinedStringDonatedArray(rhs);
+ int inlined_string_count = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (field->is_extension() || field->is_repeated() ||
+ schema_.InRealOneof(field) ||
+ field->options().ctype() != FieldOptions::STRING ||
+ !IsInlined(field)) {
+ continue;
+ }
+ inlined_string_count++;
+ }
+
+ int donated_array_size = inlined_string_count == 0
+ ? 0
+ // One extra bit for the arena dtor tracking.
+ : (inlined_string_count + 1 + 31) / 32;
+ GOOGLE_CHECK_EQ((lhs_donated_array[0] & 0x1u) == 0,
+ (rhs_donated_array[0] & 0x1u) == 0);
+ for (int i = 0; i < donated_array_size; i++) {
+ std::swap(lhs_donated_array[i], rhs_donated_array[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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ 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, int32_t);
+ CLEAR_TYPE(INT64, int64_t);
+ CLEAR_TYPE(UINT32, uint32_t);
+ CLEAR_TYPE(UINT64, uint64_t);
+ 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();
+ } else {
+ auto* str = MutableRaw<ArenaStringPtr>(message, field);
+ str->Destroy();
+ str->InitDefault();
+ }
+ break;
+ }
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ if (schema_.HasBitIndex(field) == static_cast<uint32_t>(-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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ 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<std::string> >(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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ 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<std::string> >(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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ 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 uint32_t* has_bit_set, uint32_t has_bit_index) {
+ GOOGLE_DCHECK_NE(has_bit_index, ~0u);
+ return ((has_bit_set[has_bit_index / 32] >> (has_bit_index % 32)) &
+ static_cast<uint32_t>(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 uint32_t* const has_bits =
+ schema_.HasHasbits() ? GetHasBits(message) : nullptr;
+ const uint32_t* 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 uint32_t* const oneof_case_array =
+ GetConstPointerAtOffset<uint32_t>(&message,
+ schema_.oneof_case_offset_);
+ // Equivalent to: HasOneofField(message, field)
+ if (static_cast<int64_t>(oneof_case_array[containing_oneof->index()]) ==
+ field->number()) {
+ output->push_back(field);
+ }
+ } else if (has_bits && has_bits_indices[i] != static_cast<uint32_t>(-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, int32_t, int32_t, INT32)
+DEFINE_PRIMITIVE_ACCESSORS(Int64, int64_t, int64_t, INT64)
+DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32_t, uint32_t, UINT32)
+DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64_t, uint64_t, 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
+
+// -------------------------------------------------------------------
+
+std::string 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();
+ } else {
+ const auto& str = GetField<ArenaStringPtr>(message, field);
+ return str.IsDefault() ? field->default_value_string() : str.Get();
+ }
+ }
+ }
+}
+
+const std::string& Reflection::GetStringReference(const Message& message,
+ const FieldDescriptor* field,
+ std::string* 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();
+ } else {
+ const auto& str = GetField<ArenaStringPtr>(message, field);
+ return str.IsDefault() ? field->default_value_string() : str.Get();
+ }
+ }
+ }
+}
+
+
+void Reflection::SetString(Message* message, const FieldDescriptor* field,
+ std::string 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 uint32_t index = schema_.InlinedStringIndex(field);
+ GOOGLE_DCHECK_GT(index, 0);
+ uint32_t* states =
+ &MutableInlinedStringDonatedArray(message)[index / 32];
+ uint32_t mask = ~(static_cast<uint32_t>(1) << (index % 32));
+ MutableField<InlinedStringField>(message, field)
+ ->Set(value, message->GetArenaForAllocation(),
+ IsInlinedStringDonated(*message, field), states, mask,
+ message);
+ 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.
+ if (schema_.InRealOneof(field) && !HasOneofField(*message, field)) {
+ ClearOneof(message, field->containing_oneof());
+ MutableField<ArenaStringPtr>(message, field)->InitDefault();
+ }
+ MutableField<ArenaStringPtr>(message, field)
+ ->Set(std::move(value), message->GetArenaForAllocation());
+ break;
+ }
+ }
+ }
+}
+
+
+std::string 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<std::string>(message, field, index);
+ }
+ }
+}
+
+const std::string& Reflection::GetRepeatedStringReference(
+ const Message& message, const FieldDescriptor* field, int index,
+ std::string* 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<std::string>(message, field, index);
+ }
+ }
+}
+
+
+void Reflection::SetRepeatedString(Message* message,
+ const FieldDescriptor* field, int index,
+ std::string 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<std::string>(message, field, index)
+ ->assign(std::move(value));
+ break;
+ }
+ }
+}
+
+
+void Reflection::AddString(Message* message, const FieldDescriptor* field,
+ std::string 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<std::string>(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);
+
+ int32_t 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;
+ }
+ uint32_t 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()->map_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()->map_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 std::string& 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 uint32_t* Reflection::GetHasBits(const Message& message) const {
+ GOOGLE_DCHECK(schema_.HasHasbits());
+ return &GetConstRefAtOffset<uint32_t>(message, schema_.HasBitsOffset());
+}
+
+uint32_t* Reflection::MutableHasBits(Message* message) const {
+ GOOGLE_DCHECK(schema_.HasHasbits());
+ return GetPointerAtOffset<uint32_t>(message, schema_.HasBitsOffset());
+}
+
+uint32_t* Reflection::MutableOneofCase(
+ Message* message, const OneofDescriptor* oneof_descriptor) const {
+ GOOGLE_DCHECK(!oneof_descriptor->is_synthetic());
+ return GetPointerAtOffset<uint32_t>(
+ 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 uint32_t* Reflection::GetInlinedStringDonatedArray(
+ const Message& message) const {
+ GOOGLE_DCHECK(schema_.HasInlinedString());
+ return &GetConstRefAtOffset<uint32_t>(message,
+ schema_.InlinedStringDonatedOffset());
+}
+
+uint32_t* Reflection::MutableInlinedStringDonatedArray(Message* message) const {
+ GOOGLE_DCHECK(schema_.HasInlinedString());
+ return GetPointerAtOffset<uint32_t>(message,
+ schema_.InlinedStringDonatedOffset());
+}
+
+// Simple accessors for manipulating _inlined_string_donated_;
+bool Reflection::IsInlinedStringDonated(const Message& message,
+ const FieldDescriptor* field) const {
+ uint32_t index = schema_.InlinedStringIndex(field);
+ GOOGLE_DCHECK_GT(index, 0);
+ return IsIndexInHasBitSet(GetInlinedStringDonatedArray(message), index);
+}
+
+inline void SetInlinedStringDonated(uint32_t index, uint32_t* array) {
+ array[index / 32] |= (static_cast<uint32_t>(1) << (index % 32));
+}
+
+inline void ClearInlinedStringDonated(uint32_t index, uint32_t* array) {
+ array[index / 32] &= ~(static_cast<uint32_t>(1) << (index % 32));
+}
+
+void Reflection::SwapInlinedStringDonated(Message* lhs, Message* rhs,
+ const FieldDescriptor* field) const {
+ Arena* lhs_arena = lhs->GetArenaForAllocation();
+ Arena* rhs_arena = rhs->GetArenaForAllocation();
+ // If arenas differ, inined string fields are swapped by copying values.
+ // Donation status should not be swapped.
+ if (lhs_arena != rhs_arena) {
+ return;
+ }
+ bool lhs_donated = IsInlinedStringDonated(*lhs, field);
+ bool rhs_donated = IsInlinedStringDonated(*rhs, field);
+ if (lhs_donated == rhs_donated) {
+ return;
+ }
+ // If one is undonated, both must have already registered ArenaDtor.
+ uint32_t* lhs_array = MutableInlinedStringDonatedArray(lhs);
+ uint32_t* rhs_array = MutableInlinedStringDonatedArray(rhs);
+ GOOGLE_CHECK_EQ(lhs_array[0] & 0x1u, 0u);
+ GOOGLE_CHECK_EQ(rhs_array[0] & 0x1u, 0u);
+ // Swap donation status bit.
+ uint32_t index = schema_.InlinedStringIndex(field);
+ GOOGLE_DCHECK_GT(index, 0);
+ if (rhs_donated) {
+ SetInlinedStringDonated(index, lhs_array);
+ ClearInlinedStringDonated(index, rhs_array);
+ } else { // lhs_donated
+ ClearInlinedStringDonated(index, lhs_array);
+ SetInlinedStringDonated(index, rhs_array);
+ }
+}
+
+// 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<uint32_t>(-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<int32_t>(message, field) != 0;
+ case FieldDescriptor::CPPTYPE_INT64:
+ return GetRaw<int64_t>(message, field) != 0;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return GetRaw<uint32_t>(message, field) != 0;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return GetRaw<uint64_t>(message, field) != 0;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ static_assert(sizeof(uint32_t) == sizeof(float),
+ "Code assumes uint32_t and float are the same size.");
+ return GetRaw<uint32_t>(message, field) != 0;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ static_assert(sizeof(uint64_t) == sizeof(double),
+ "Code assumes uint64_t and double are the same size.");
+ return GetRaw<uint64_t>(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 uint32_t index = schema_.HasBitIndex(field);
+ if (index == static_cast<uint32_t>(-1)) return;
+ MutableHasBits(message)[index / 32] |=
+ (static_cast<uint32_t>(1) << (index % 32));
+}
+
+void Reflection::ClearBit(Message* message,
+ const FieldDescriptor* field) const {
+ GOOGLE_DCHECK(!field->options().weak());
+ const uint32_t index = schema_.HasBitIndex(field);
+ if (index == static_cast<uint32_t>(-1)) return;
+ MutableHasBits(message)[index / 32] &=
+ ~(static_cast<uint32_t>(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
+ uint32_t 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();
+ break;
+ }
+ }
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ delete *MutableRaw<Message*>(message, field);
+ break;
+ default:
+ break;
+ }
+ } else {
+ }
+
+ *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(int32_t, FieldDescriptor::CPPTYPE_INT32, -1);
+HANDLE_TYPE(int64_t, FieldDescriptor::CPPTYPE_INT64, -1);
+HANDLE_TYPE(uint32_t, FieldDescriptor::CPPTYPE_UINT32, -1);
+HANDLE_TYPE(uint64_t, 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 int32_t).";
+ 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 uint32_t* 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 uint32_t* 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 uint32_t* 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, uint32_t offset,
+ uint32_t /*tag*/, uint32_t /*has_offset*/,
+ io::CodedOutputStream* output) {
+ const void* ptr = base + offset;
+ const InternalMetadata* metadata = static_cast<const InternalMetadata*>(ptr);
+ if (metadata->have_unknown_fields()) {
+ metadata->unknown_fields<UnknownFieldSet>(UnknownFieldSet::default_instance)
+ .SerializeToCodedStream(output);
+ }
+}
+
+bool IsDescendant(Message& root, const Message& message) {
+ const Reflection* reflection = root.GetReflection();
+ std::vector<const FieldDescriptor*> fields;
+ reflection->ListFieldsOmitStripped(root, &fields);
+
+ for (const auto* field : fields) {
+ // Skip non-message fields.
+ if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
+
+ // Optional messages.
+ if (!field->is_repeated()) {
+ Message* sub_message = reflection->MutableMessage(&root, field);
+ if (sub_message == &message || IsDescendant(*sub_message, message)) {
+ return true;
+ }
+ continue;
+ }
+
+ // Repeated messages.
+ if (!IsMapFieldInApi(field)) {
+ int count = reflection->FieldSize(root, field);
+ for (int i = 0; i < count; i++) {
+ Message* sub_message =
+ reflection->MutableRepeatedMessage(&root, field, i);
+ if (sub_message == &message || IsDescendant(*sub_message, message)) {
+ return true;
+ }
+ }
+ continue;
+ }
+
+ // Map field: if accessed as repeated fields, messages are *copied* and
+ // matching pointer won't work. Must directly access map.
+ constexpr int kValIdx = 1;
+ const FieldDescriptor* val_field = field->message_type()->field(kValIdx);
+ // Skip map fields whose value type is not message.
+ if (val_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
+
+ MapIterator end = reflection->MapEnd(&root, field);
+ for (auto iter = reflection->MapBegin(&root, field); iter != end; ++iter) {
+ Message* sub_message = iter.MutableValueRef()->MutableMessageValue();
+ if (sub_message == &message || IsDescendant(*sub_message, message)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
diff --git a/toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.h b/toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.h
new file mode 100644
index 0000000000..334b2ccf1d
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.h
@@ -0,0 +1,354 @@
+// 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 <google/protobuf/stubs/casts.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/port.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_enum_reflection.h>
+#include <google/protobuf/unknown_field_set.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 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 uint32_t
+// 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.
+ uint32_t GetObjectSize() const { return static_cast<uint32_t>(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.
+ uint32_t GetFieldOffsetNonOneof(const FieldDescriptor* field) const {
+ GOOGLE_DCHECK(!InRealOneof(field));
+ return OffsetValue(offsets_[field->index()], field->type());
+ }
+
+ // Offset of any field.
+ uint32_t 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());
+ }
+
+ uint32_t GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const {
+ return static_cast<uint32_t>(oneof_case_offset_) +
+ static_cast<uint32_t>(
+ static_cast<size_t>(oneof_descriptor->index()) *
+ sizeof(uint32_t));
+ }
+
+ bool HasHasbits() const { return has_bits_offset_ != -1; }
+
+ // Bit index within the bit array of hasbits. Bit order is low-to-high.
+ uint32_t HasBitIndex(const FieldDescriptor* field) const {
+ if (has_bits_offset_ == -1) return static_cast<uint32_t>(-1);
+ GOOGLE_DCHECK(HasHasbits());
+ return has_bit_indices_[field->index()];
+ }
+
+ // Byte offset of the hasbits array.
+ uint32_t HasBitsOffset() const {
+ GOOGLE_DCHECK(HasHasbits());
+ return static_cast<uint32_t>(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.
+ uint32_t InlinedStringIndex(const FieldDescriptor* field) const {
+ GOOGLE_DCHECK(HasInlinedString());
+ return inlined_string_indices_[field->index()];
+ }
+
+ // Byte offset of the _inlined_string_donated_ array.
+ uint32_t InlinedStringDonatedOffset() const {
+ GOOGLE_DCHECK(HasInlinedString());
+ return static_cast<uint32_t>(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.
+ uint32_t GetMetadataOffset() const {
+ return static_cast<uint32_t>(metadata_offset_);
+ }
+
+ // Whether this message has an ExtensionSet.
+ bool HasExtensionSet() const { return extensions_offset_ != -1; }
+
+ // The offset of the ExtensionSet in this message.
+ uint32_t GetExtensionSetOffset() const {
+ GOOGLE_DCHECK(HasExtensionSet());
+ return static_cast<uint32_t>(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;
+ }
+
+ 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 uint32_t* offsets_;
+ const uint32_t* 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 uint32_t* 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 uint32_t OffsetValue(uint32_t v, FieldDescriptor::Type type) {
+ if (type == FieldDescriptor::TYPE_MESSAGE ||
+ type == FieldDescriptor::TYPE_STRING ||
+ type == FieldDescriptor::TYPE_BYTES) {
+ return v & 0xFFFFFFFEu;
+ }
+ return v;
+ }
+
+ static bool Inlined(uint32_t 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 {
+ int32_t offsets_index;
+ int32_t has_bit_indices_index;
+ int32_t 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 uint32_t* 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,
+ uint32_t offset, uint32_t tag,
+ uint32_t 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/toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_decl.h b/toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_decl.h
new file mode 100644
index 0000000000..b1bb1def70
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_decl.h
@@ -0,0 +1,312 @@
+// 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 <array>
+#include <cstddef>
+#include <cstdint>
+#include <type_traits>
+
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/parse_context.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) {}
+
+ // Fast table entry constructor:
+ constexpr TcFieldData(uint16_t coded_tag, uint8_t hasbit_idx, uint8_t aux_idx,
+ uint16_t offset)
+ : data(uint64_t{offset} << 48 | //
+ uint64_t{aux_idx} << 24 | //
+ uint64_t{hasbit_idx} << 16 | //
+ uint64_t{coded_tag}) {}
+
+ // Fields used in fast table parsing:
+ //
+ // Bit:
+ // +-----------+-------------------+
+ // |63 .. 32|31 .. 0|
+ // +---------------+---------------+
+ // : . : . : . 16|=======| [16] coded_tag()
+ // : . : . : 24|===| . : [ 8] hasbit_idx()
+ // : . : . 32|===| : . : [ 8] aux_idx()
+ // : . 48:---.---: . : . : [16] (unused)
+ // |=======| . : . : . : [16] offset()
+ // +-----------+-------------------+
+ // |63 .. 32|31 .. 0|
+ // +---------------+---------------+
+
+ 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); }
+ uint8_t aux_idx() const { return static_cast<uint8_t>(data >> 24); }
+ uint16_t offset() const { return static_cast<uint16_t>(data >> 48); }
+
+ // Fields used in mini table parsing:
+ //
+ // Bit:
+ // +-----------+-------------------+
+ // |63 .. 32|31 .. 0|
+ // +---------------+---------------+
+ // : . : . |===============| [32] tag() (decoded)
+ // |===============| . : . : [32] entry_offset()
+ // +-----------+-------------------+
+ // |63 .. 32|31 .. 0|
+ // +---------------+---------------+
+
+ uint32_t tag() const { return static_cast<uint32_t>(data); }
+ uint32_t entry_offset() const { return static_cast<uint32_t>(data >> 32); }
+
+ uint64_t data;
+};
+
+struct TcParseTableBase;
+
+// TailCallParseFunc is the function pointer type used in the tailcall table.
+typedef const char* (*TailCallParseFunc)(PROTOBUF_TC_PARAM_DECL);
+
+namespace field_layout {
+struct Offset {
+ uint32_t off;
+};
+} // namespace field_layout
+
+#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(uint64_t) TcParseTableBase {
+ // Common attributes for message layout:
+ uint16_t has_bits_offset;
+ uint16_t extension_offset;
+ uint32_t extension_range_low;
+ uint32_t extension_range_high;
+ uint32_t max_field_number;
+ uint8_t fast_idx_mask;
+ uint16_t lookup_table_offset;
+ uint32_t skipmap32;
+ uint32_t field_entries_offset;
+ uint16_t num_field_entries;
+
+ uint16_t num_aux_entries;
+ uint32_t aux_offset;
+
+ const MessageLite* default_instance;
+
+ // Handler for fields which are not handled by table dispatch.
+ TailCallParseFunc fallback;
+
+ // This constructor exactly follows the field layout, so it's technically
+ // not necessary. However, it makes it much much easier to add or re-arrange
+ // fields, because it can be overloaded with an additional constructor,
+ // temporarily allowing both old and new protocol buffer headers to be
+ // compiled.
+ constexpr TcParseTableBase(
+ uint16_t has_bits_offset, uint16_t extension_offset,
+ uint32_t extension_range_low, uint32_t extension_range_high,
+ uint32_t max_field_number, uint8_t fast_idx_mask,
+ uint16_t lookup_table_offset, uint32_t skipmap32,
+ uint32_t field_entries_offset, uint16_t num_field_entries,
+ uint16_t num_aux_entries, uint32_t aux_offset,
+ const MessageLite* default_instance, TailCallParseFunc fallback)
+ : has_bits_offset(has_bits_offset),
+ extension_offset(extension_offset),
+ extension_range_low(extension_range_low),
+ extension_range_high(extension_range_high),
+ max_field_number(max_field_number),
+ fast_idx_mask(fast_idx_mask),
+ lookup_table_offset(lookup_table_offset),
+ skipmap32(skipmap32),
+ field_entries_offset(field_entries_offset),
+ num_field_entries(num_field_entries),
+ num_aux_entries(num_aux_entries),
+ aux_offset(aux_offset),
+ default_instance(default_instance),
+ fallback(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;
+ }
+
+ // Returns a begin iterator (pointer) to the start of the field lookup table.
+ const uint16_t* field_lookup_begin() const {
+ return reinterpret_cast<const uint16_t*>(reinterpret_cast<uintptr_t>(this) +
+ lookup_table_offset);
+ }
+
+ // Field entry for all fields.
+ struct FieldEntry {
+ uint32_t offset; // offset in the message object
+ int32_t has_idx; // has-bit index
+ uint16_t aux_idx; // index for `field_aux`.
+ uint16_t type_card; // `FieldType` and `Cardinality` (see _impl.h)
+ };
+
+ // Returns a begin iterator (pointer) to the start of the field entries array.
+ const FieldEntry* field_entries_begin() const {
+ return reinterpret_cast<const FieldEntry*>(
+ reinterpret_cast<uintptr_t>(this) + field_entries_offset);
+ }
+
+ // Auxiliary entries for field types that need extra information.
+ union FieldAux {
+ constexpr FieldAux() : message_default(nullptr) {}
+ constexpr FieldAux(bool (*enum_validator)(int))
+ : enum_validator(enum_validator) {}
+ constexpr FieldAux(field_layout::Offset off) : offset(off.off) {}
+ constexpr FieldAux(int16_t range_start, uint16_t range_length)
+ : enum_range{range_start, range_length} {}
+ constexpr FieldAux(const MessageLite* msg) : message_default(msg) {}
+ bool (*enum_validator)(int);
+ struct {
+ int16_t start; // minimum enum number (if it fits)
+ uint16_t length; // length of range (i.e., max = start + length - 1)
+ } enum_range;
+ uint32_t offset;
+ const MessageLite* message_default;
+ };
+ const FieldAux* field_aux(uint32_t idx) const {
+ return reinterpret_cast<const FieldAux*>(reinterpret_cast<uintptr_t>(this) +
+ aux_offset) +
+ idx;
+ }
+ const FieldAux* field_aux(const FieldEntry* entry) const {
+ return field_aux(entry->aux_idx);
+ }
+
+ // Field name data
+ const char* name_data() const {
+ return reinterpret_cast<const char*>(reinterpret_cast<uintptr_t>(this) +
+ aux_offset +
+ num_aux_entries * sizeof(FieldAux));
+ }
+};
+
+#if defined(_MSC_VER) && !defined(_WIN64)
+#pragma warning(pop)
+#endif
+
+static_assert(sizeof(TcParseTableBase::FastFieldEntry) <= 16,
+ "Fast field entry is too big.");
+static_assert(sizeof(TcParseTableBase::FieldEntry) <= 16,
+ "Field entry is too big.");
+
+template <size_t kFastTableSizeLog2, size_t kNumFieldEntries = 0,
+ size_t kNumFieldAux = 0, size_t kNameTableSize = 0,
+ size_t kFieldLookupSize = 2>
+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::fast_entry()` instead of accessing
+ // this field directly.
+ std::array<TcParseTableBase::FastFieldEntry, (1 << kFastTableSizeLog2)>
+ fast_entries;
+
+ // Just big enough to find all the field entries.
+ std::array<uint16_t, kFieldLookupSize> field_lookup_table;
+ // Entries for all fields:
+ std::array<TcParseTableBase::FieldEntry, kNumFieldEntries> field_entries;
+ std::array<TcParseTableBase::FieldAux, kNumFieldAux> aux_entries;
+ std::array<char, kNameTableSize> field_names;
+};
+
+// Partial specialization: if there are no aux entries, there will be no array.
+// In C++, arrays cannot have length 0, but (C++11) std::array<T, 0> is valid.
+// However, different implementations have different sizeof(std::array<T, 0>).
+// Skipping the member makes offset computations portable.
+template <size_t kFastTableSizeLog2, size_t kNumFieldEntries,
+ size_t kNameTableSize, size_t kFieldLookupSize>
+struct TcParseTable<kFastTableSizeLog2, kNumFieldEntries, 0, kNameTableSize,
+ kFieldLookupSize> {
+ TcParseTableBase header;
+ std::array<TcParseTableBase::FastFieldEntry, (1 << kFastTableSizeLog2)>
+ fast_entries;
+ std::array<uint16_t, kFieldLookupSize> field_lookup_table;
+ std::array<TcParseTableBase::FieldEntry, kNumFieldEntries> field_entries;
+ std::array<char, kNameTableSize> field_names;
+};
+
+// Partial specialization: if there are no fields at all, then we can save space
+// by skipping the field numbers and entries.
+template <size_t kNameTableSize, size_t kFieldLookupSize>
+struct TcParseTable<0, 0, 0, kNameTableSize, kFieldLookupSize> {
+ TcParseTableBase header;
+ // N.B.: the fast entries are sized by log2, so 2**0 fields = 1 entry.
+ // The fast parsing loop will always use this entry, so it must be present.
+ std::array<TcParseTableBase::FastFieldEntry, 1> fast_entries;
+ std::array<uint16_t, kFieldLookupSize> field_lookup_table;
+ std::array<char, kNameTableSize> field_names;
+};
+
+static_assert(std::is_standard_layout<TcParseTable<1>>::value,
+ "TcParseTable must be standard layout.");
+
+static_assert(offsetof(TcParseTable<1>, fast_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/toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_full.cc b/toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_full.cc
new file mode 100644
index 0000000000..b77bb8d8e3
--- /dev/null
+++ b/toolkit/components/protobuf/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/extension_set.h>
+#include <google/protobuf/generated_message_tctable_impl.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/parse_context.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/toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_impl.h b/toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_impl.h
new file mode 100644
index 0000000000..21fa5332d3
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_impl.h
@@ -0,0 +1,553 @@
+// 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/port.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/parse_context.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 {
+
+// Field layout enums.
+//
+// Structural information about fields is packed into a 16-bit value. The enum
+// types below represent bitwise fields, along with their respective widths,
+// shifts, and masks.
+//
+// Bit:
+// +-----------------------+-----------------------+
+// |15 .. 8|7 .. 0|
+// +-----------------------+-----------------------+
+// : . : . : . : . : . : . : 3|========| [3] FieldType
+// : : : : : : 5|=====| : : [2] FieldCardinality
+// : . : . : . : . 8|========| : . : . : [3] FieldRep
+// : : : 10|=====| : : : : [2] TransformValidation
+// : . : .12|=====| . : . : . : . : . : [2] FormatDiscriminator
+// +-----------------------+-----------------------+
+// |15 .. 8|7 .. 0|
+// +-----------------------+-----------------------+
+//
+namespace field_layout {
+// clang-format off
+
+// Field kind (3 bits):
+// These values broadly represent a wire type and an in-memory storage class.
+enum FieldKind : uint16_t {
+ kFkShift = 0,
+ kFkBits = 3,
+ kFkMask = ((1 << kFkBits) - 1) << kFkShift,
+
+ kFkNone = 0,
+ kFkVarint, // WT=0 rep=8,32,64 bits
+ kFkPackedVarint, // WT=2 rep=8,32,64 bits
+ kFkFixed, // WT=1,5 rep=32,64 bits
+ kFkPackedFixed, // WT=2 rep=32,64 bits
+ kFkString, // WT=2 rep=various
+ kFkMessage, // WT=2,3,4 rep=MessageLite*
+ // Maps are a special case of Message, but use different parsing logic.
+ kFkMap, // WT=2 rep=Map(Lite)<various, various>
+};
+
+static_assert(kFkMap < (1 << kFkBits), "too many types");
+
+// Cardinality (2 bits):
+// These values determine how many values a field can have and its presence.
+// Packed fields are represented in FieldType.
+enum Cardinality : uint16_t {
+ kFcShift = kFkShift + kFkBits,
+ kFcBits = 2,
+ kFcMask = ((1 << kFcBits) - 1) << kFcShift,
+
+ kFcSingular = 0,
+ kFcOptional = 1 << kFcShift,
+ kFcRepeated = 2 << kFcShift,
+ kFcOneof = 3 << kFcShift,
+};
+
+// Field representation (3 bits):
+// These values are the specific refinements of storage classes in FieldType.
+enum FieldRep : uint16_t {
+ kRepShift = kFcShift + kFcBits,
+ kRepBits = 3,
+ kRepMask = ((1 << kRepBits) - 1) << kRepShift,
+
+ // Numeric types (used for optional and repeated fields):
+ kRep8Bits = 0,
+ kRep32Bits = 2 << kRepShift,
+ kRep64Bits = 3 << kRepShift,
+ // String types:
+ kRepAString = 0, // ArenaStringPtr
+ kRepIString = 1 << kRepShift, // InlinedString
+ kRepCord = 2 << kRepShift, // absl::Cord
+ kRepSPiece = 3 << kRepShift, // StringPieceField
+ kRepSString = 4 << kRepShift, // std::string*
+ // Message types (WT=2 unless otherwise noted):
+ kRepMessage = 0, // MessageLite*
+ kRepGroup = 1 << kRepShift, // MessageLite* (WT=3,4)
+ kRepLazy = 2 << kRepShift, // LazyField*
+ kRepIWeak = 3 << kRepShift, // ImplicitWeak
+};
+
+// Transform/validation (2 bits):
+// These values determine transforms or validation to/from wire format.
+enum TransformValidation : uint16_t {
+ kTvShift = kRepShift + kRepBits,
+ kTvBits = 2,
+ kTvMask = ((1 << kTvBits) - 1) << kTvShift,
+
+ // Varint fields:
+ kTvZigZag = 1 << kTvShift,
+ kTvEnum = 2 << kTvShift, // validate using generated _IsValid()
+ kTvRange = 3 << kTvShift, // validate using FieldAux::enum_range
+ // String fields:
+ kTvUtf8Debug = 1 << kTvShift, // proto2
+ kTvUtf8 = 2 << kTvShift, // proto3
+};
+
+static_assert((kTvEnum & kTvRange) != 0,
+ "enum validation types must share a bit");
+static_assert((kTvEnum & kTvRange & kTvZigZag) == 0,
+ "zigzag encoding is not enum validation");
+
+// Format discriminators (2 bits):
+enum FormatDiscriminator : uint16_t {
+ kFmtShift = kTvShift + kTvBits,
+ kFmtBits = 2,
+ kFmtMask = ((1 << kFmtBits) - 1) << kFmtShift,
+
+ // Numeric:
+ kFmtUnsigned = 1 << kFmtShift, // fixed, varint
+ kFmtSigned = 2 << kFmtShift, // fixed, varint
+ kFmtFloating = 3 << kFmtShift, // fixed
+ kFmtEnum = 3 << kFmtShift, // varint
+ // Strings:
+ kFmtUtf8 = 1 << kFmtShift, // string (proto3, enforce_utf8=true)
+ kFmtUtf8Escape = 2 << kFmtShift, // string (proto2, enforce_utf8=false)
+ // Bytes:
+ kFmtArray = 1 << kFmtShift, // bytes
+ // Messages:
+ kFmtShow = 1 << kFmtShift, // message, map
+};
+
+// Update this assertion (and comments above) when adding or removing bits:
+static_assert(kFmtShift + kFmtBits == 12, "number of bits changed");
+
+// This assertion should not change unless the storage width changes:
+static_assert(kFmtShift + kFmtBits <= 16, "too many bits");
+
+// Convenience aliases (16 bits, with format):
+enum FieldType : uint16_t {
+ // Numeric types:
+ kBool = kFkVarint | kRep8Bits,
+
+ kFixed32 = kFkFixed | kRep32Bits | kFmtUnsigned,
+ kUInt32 = kFkVarint | kRep32Bits | kFmtUnsigned,
+ kSFixed32 = kFkFixed | kRep32Bits | kFmtSigned,
+ kInt32 = kFkVarint | kRep32Bits | kFmtSigned,
+ kSInt32 = kFkVarint | kRep32Bits | kFmtSigned | kTvZigZag,
+ kFloat = kFkFixed | kRep32Bits | kFmtFloating,
+ kEnum = kFkVarint | kRep32Bits | kFmtEnum | kTvEnum,
+ kEnumRange = kFkVarint | kRep32Bits | kFmtEnum | kTvRange,
+ kOpenEnum = kFkVarint | kRep32Bits | kFmtEnum,
+
+ kFixed64 = kFkFixed | kRep64Bits | kFmtUnsigned,
+ kUInt64 = kFkVarint | kRep64Bits | kFmtUnsigned,
+ kSFixed64 = kFkFixed | kRep64Bits | kFmtSigned,
+ kInt64 = kFkVarint | kRep64Bits | kFmtSigned,
+ kSInt64 = kFkVarint | kRep64Bits | kFmtSigned | kTvZigZag,
+ kDouble = kFkFixed | kRep64Bits | kFmtFloating,
+
+ kPackedBool = kFkPackedVarint | kRep8Bits,
+
+ kPackedFixed32 = kFkPackedFixed | kRep32Bits | kFmtUnsigned,
+ kPackedUInt32 = kFkPackedVarint | kRep32Bits | kFmtUnsigned,
+ kPackedSFixed32 = kFkPackedFixed | kRep32Bits | kFmtSigned,
+ kPackedInt32 = kFkPackedVarint | kRep32Bits | kFmtSigned,
+ kPackedSInt32 = kFkPackedVarint | kRep32Bits | kFmtSigned | kTvZigZag,
+ kPackedFloat = kFkPackedFixed | kRep32Bits | kFmtFloating,
+ kPackedEnum = kFkPackedVarint | kRep32Bits | kFmtEnum | kTvEnum,
+ kPackedEnumRange = kFkPackedVarint | kRep32Bits | kFmtEnum | kTvRange,
+ kPackedOpenEnum = kFkPackedVarint | kRep32Bits | kFmtEnum,
+
+ kPackedFixed64 = kFkPackedFixed | kRep64Bits | kFmtUnsigned,
+ kPackedUInt64 = kFkPackedVarint | kRep64Bits | kFmtUnsigned,
+ kPackedSFixed64 = kFkPackedFixed | kRep64Bits | kFmtSigned,
+ kPackedInt64 = kFkPackedVarint | kRep64Bits | kFmtSigned,
+ kPackedSInt64 = kFkPackedVarint | kRep64Bits | kFmtSigned | kTvZigZag,
+ kPackedDouble = kFkPackedFixed | kRep64Bits | kFmtFloating,
+
+ // String types:
+ kBytes = kFkString | kFmtArray,
+ kRawString = kFkString | kFmtUtf8 | kTvUtf8Debug,
+ kUtf8String = kFkString | kFmtUtf8 | kTvUtf8,
+
+ // Message types:
+ kMessage = kFkMessage,
+
+ // Map types:
+ kMap = kFkMap,
+};
+
+// clang-format on
+} // namespace field_layout
+
+// 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
+
+#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 PROTOBUF_EXPORT TcParser final {
+ public:
+ static const char* GenericFallback(PROTOBUF_TC_PARAM_DECL);
+ static const char* GenericFallbackLite(PROTOBUF_TC_PARAM_DECL);
+
+ static const char* ParseLoop(MessageLite* msg, const char* ptr,
+ ParseContext* ctx,
+ const TcParseTableBase* table);
+
+ // Functions referenced by generated fast tables (numeric types):
+ // F: fixed V: varint Z: zigzag
+ // 8/32/64: storage type width (bits)
+ // S: singular R: repeated P: packed
+ // 1/2: tag length (bytes)
+
+ // Fixed:
+ static const char* FastF32S1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastF32S2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastF32R1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastF32R2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastF32P1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastF32P2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastF64S1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastF64S2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastF64R1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastF64R2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastF64P1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastF64P2(PROTOBUF_TC_PARAM_DECL);
+
+ // Varint:
+ static const char* FastV8S1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV8S2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV8R1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV8R2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV8P1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV8P2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV32S1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV32S2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV32R1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV32R2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV32P1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV32P2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV64S1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV64S2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV64R1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV64R2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV64P1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastV64P2(PROTOBUF_TC_PARAM_DECL);
+
+ // Varint (with zigzag):
+ static const char* FastZ32S1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastZ32S2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastZ32R1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastZ32R2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastZ32P1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastZ32P2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastZ64S1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastZ64S2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastZ64R1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastZ64R2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastZ64P1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastZ64P2(PROTOBUF_TC_PARAM_DECL);
+
+ // Functions referenced by generated fast tables (closed enum):
+ // E: closed enum (N.B.: open enums use V32, above)
+ // r: enum range v: enum validator (_IsValid function)
+ // S: singular R: repeated
+ // 1/2: tag length (bytes)
+ static const char* FastErS1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastErS2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastErR1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastErR2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastEvS1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastEvS2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastEvR1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastEvR2(PROTOBUF_TC_PARAM_DECL);
+
+ // Functions referenced by generated fast tables (string types):
+ // B: bytes S: string U: UTF-8 string
+ // (empty): ArenaStringPtr i: InlinedString
+ // S: singular R: repeated
+ // 1/2: tag length (bytes)
+ static const char* FastBS1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastBS2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastBR1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastBR2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastSS1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastSS2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastSR1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastSR2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastUS1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastUS2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastUR1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastUR2(PROTOBUF_TC_PARAM_DECL);
+
+ static const char* FastBiS1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastBiS2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastSiS1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastSiS2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastUiS1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastUiS2(PROTOBUF_TC_PARAM_DECL);
+
+ // Functions referenced by generated fast tables (message types):
+ // M: message G: group
+ // S: singular R: repeated
+ // 1/2: tag length (bytes)
+ static const char* FastMS1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastMS2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastMR1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastMR2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastGS1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastGS2(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastGR1(PROTOBUF_TC_PARAM_DECL);
+ static const char* FastGR2(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;
+ }
+
+ template <typename T>
+ static inline const T& RefAt(const void* x, size_t offset) {
+ const T* target =
+ reinterpret_cast<const T*>(static_cast<const 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;
+ }
+
+ template <typename T>
+ static inline T ReadAt(const void* x, size_t offset) {
+ T out;
+ memcpy(&out, static_cast<const char*>(x) + offset, sizeof(T));
+ return out;
+ }
+
+ // Mini parsing:
+ //
+ // This function parses a field from incoming data based on metadata stored in
+ // the message definition. If the field is not defined in the message, it is
+ // stored in either the ExtensionSet (if applicable) or the UnknownFieldSet.
+ //
+ // NOTE: Currently, this function only calls the table-level fallback
+ // function, so it should only be called as the fallback from fast table
+ // parsing.
+ static const char* MiniParse(PROTOBUF_TC_PARAM_DECL);
+
+ private:
+ friend class GeneratedTcTableLiteTest;
+
+ template <typename TagType, bool group_coding>
+ static inline const char* SingularParseMessageAuxImpl(PROTOBUF_TC_PARAM_DECL);
+ template <typename TagType, bool group_coding>
+ static inline const char* RepeatedParseMessageAuxImpl(PROTOBUF_TC_PARAM_DECL);
+
+ static inline PROTOBUF_ALWAYS_INLINE void SyncHasbits(
+ MessageLite* msg, uint64_t hasbits, const TcParseTableBase* table) {
+ const uint32_t has_bits_offset = table->has_bits_offset;
+ if (has_bits_offset) {
+ // Only the first 32 has-bits are updated. Nothing above those is stored,
+ // but e.g. messages without has-bits update the upper bits.
+ RefAt<uint32_t>(msg, has_bits_offset) = static_cast<uint32_t>(hasbits);
+ }
+ }
+
+ static const char* TagDispatch(PROTOBUF_TC_PARAM_DECL);
+ static const char* ToTagDispatch(PROTOBUF_TC_PARAM_DECL);
+ static const char* ToParseLoop(PROTOBUF_TC_PARAM_DECL);
+ static const char* Error(PROTOBUF_TC_PARAM_DECL);
+
+ static const char* FastUnknownEnumFallback(PROTOBUF_TC_PARAM_DECL);
+
+ class ScopedArenaSwap;
+
+ 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);
+ CHK_(ptr);
+ uint32_t tag = data.tag();
+ if ((tag & 7) == WireFormatLite::WIRETYPE_END_GROUP || tag == 0) {
+ ctx->SetLastTag(tag);
+ return ptr;
+ }
+ uint32_t num = tag >> 3;
+ if (table->extension_range_low <= num &&
+ num <= table->extension_range_high) {
+ return RefAt<ExtensionSet>(msg, table->extension_offset)
+ .ParseField(tag, ptr,
+ static_cast<const MessageBaseT*>(table->default_instance),
+ &msg->_internal_metadata_, ctx);
+ }
+ return UnknownFieldParse(
+ tag, msg->_internal_metadata_.mutable_unknown_fields<UnknownFieldsT>(),
+ ptr, ctx);
+#undef CHK_
+ }
+
+ // Note: `inline` is needed on template function declarations below to avoid
+ // -Wattributes diagnostic in GCC.
+
+ // Implementations for fast fixed field parsing functions:
+ template <typename LayoutType, typename TagType>
+ static inline const char* SingularFixed(PROTOBUF_TC_PARAM_DECL);
+ template <typename LayoutType, typename TagType>
+ static inline const char* RepeatedFixed(PROTOBUF_TC_PARAM_DECL);
+ template <typename LayoutType, typename TagType>
+ static inline const char* PackedFixed(PROTOBUF_TC_PARAM_DECL);
+
+ // Implementations for fast varint field parsing functions:
+ template <typename FieldType, typename TagType, bool zigzag = false>
+ static inline const char* SingularVarint(PROTOBUF_TC_PARAM_DECL);
+ template <typename FieldType, typename TagType, bool zigzag = false>
+ static inline const char* RepeatedVarint(PROTOBUF_TC_PARAM_DECL);
+ template <typename FieldType, typename TagType, bool zigzag = false>
+ static inline const char* PackedVarint(PROTOBUF_TC_PARAM_DECL);
+
+ // Helper for ints > 127:
+ template <typename FieldType, typename TagType, bool zigzag = false>
+ static const char* SingularVarBigint(PROTOBUF_TC_PARAM_DECL);
+
+ // Implementations for fast enum field parsing functions:
+ template <typename TagType, uint16_t xform_val>
+ static inline const char* SingularEnum(PROTOBUF_TC_PARAM_DECL);
+ template <typename TagType, uint16_t xform_val>
+ static inline const char* RepeatedEnum(PROTOBUF_TC_PARAM_DECL);
+
+ // Implementations for fast string field parsing functions:
+ enum Utf8Type { kNoUtf8 = 0, kUtf8 = 1, kUtf8ValidateOnly = 2 };
+ template <typename TagType, Utf8Type utf8>
+ static inline const char* SingularString(PROTOBUF_TC_PARAM_DECL);
+ template <typename TagType, Utf8Type utf8>
+ static inline const char* RepeatedString(PROTOBUF_TC_PARAM_DECL);
+
+ // Mini field lookup:
+ static const TcParseTableBase::FieldEntry* FindFieldEntry(
+ const TcParseTableBase* table, uint32_t field_num);
+ static StringPiece MessageName(const TcParseTableBase* table);
+ static StringPiece FieldName(const TcParseTableBase* table,
+ const TcParseTableBase::FieldEntry*);
+ static bool ChangeOneof(const TcParseTableBase* table,
+ const TcParseTableBase::FieldEntry& entry,
+ uint32_t field_num, ParseContext* ctx,
+ MessageLite* msg);
+
+ // UTF-8 validation:
+ static void ReportFastUtf8Error(uint32_t decoded_tag,
+ const TcParseTableBase* table);
+ static bool MpVerifyUtf8(StringPiece wire_bytes,
+ const TcParseTableBase* table,
+ const TcParseTableBase::FieldEntry& entry,
+ uint16_t xform_val);
+
+ // For FindFieldEntry tests:
+ friend class FindFieldEntryTest;
+ static constexpr const uint32_t kMtSmallScanSize = 4;
+
+ // Mini parsing:
+ static const char* MpVarint(PROTOBUF_TC_PARAM_DECL);
+ static const char* MpRepeatedVarint(PROTOBUF_TC_PARAM_DECL);
+ static const char* MpPackedVarint(PROTOBUF_TC_PARAM_DECL);
+ static const char* MpFixed(PROTOBUF_TC_PARAM_DECL);
+ static const char* MpRepeatedFixed(PROTOBUF_TC_PARAM_DECL);
+ static const char* MpPackedFixed(PROTOBUF_TC_PARAM_DECL);
+ static const char* MpString(PROTOBUF_TC_PARAM_DECL);
+ static const char* MpRepeatedString(PROTOBUF_TC_PARAM_DECL);
+ static const char* MpMessage(PROTOBUF_TC_PARAM_DECL);
+ static const char* MpRepeatedMessage(PROTOBUF_TC_PARAM_DECL);
+ static const char* MpMap(PROTOBUF_TC_PARAM_DECL);
+};
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_lite.cc b/toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_lite.cc
new file mode 100644
index 0000000000..9993811dca
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/generated_message_tctable_lite.cc
@@ -0,0 +1,1859 @@
+// 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 <numeric>
+
+#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/inlined_string_field.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/parse_context.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 {
+
+using FieldEntry = TcParseTableBase::FieldEntry;
+
+//////////////////////////////////////////////////////////////////////////////
+// Template instantiations:
+//////////////////////////////////////////////////////////////////////////////
+
+#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, std::string>(PROTOBUF_TC_PARAM_PASS);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Core fast parsing implementation:
+//////////////////////////////////////////////////////////////////////////////
+
+class TcParser::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_;
+};
+
+PROTOBUF_NOINLINE const char* TcParser::ParseLoop(
+ MessageLite* msg, const char* ptr, ParseContext* ctx,
+ const TcParseTableBase* table) {
+ ScopedArenaSwap saved(msg, ctx);
+ while (!ctx->Done(&ptr)) {
+ // Unconditionally read has bits, even if we don't have has bits.
+ // has_bits_offset will be 0 and we will just read something valid.
+ uint64_t hasbits = ReadAt<uint32_t>(msg, table->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;
+}
+
+ // Dispatch to the designated parse function
+inline PROTOBUF_ALWAYS_INLINE const char* TcParser::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.
+inline PROTOBUF_ALWAYS_INLINE const char* TcParser::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);
+}
+
+inline PROTOBUF_ALWAYS_INLINE const char* TcParser::ToParseLoop(
+ PROTOBUF_TC_PARAM_DECL) {
+ (void)data;
+ (void)ctx;
+ SyncHasbits(msg, hasbits, table);
+ return ptr;
+}
+
+inline PROTOBUF_ALWAYS_INLINE const char* TcParser::Error(
+ PROTOBUF_TC_PARAM_DECL) {
+ (void)data;
+ (void)ctx;
+ (void)ptr;
+ SyncHasbits(msg, hasbits, table);
+ return nullptr;
+}
+
+// On the fast path, a (matching) 1-byte tag already has the decoded value.
+static uint32_t FastDecodeTag(uint8_t coded_tag) {
+ return coded_tag;
+}
+
+// On the fast path, a (matching) 2-byte tag always needs to be decoded.
+static uint32_t FastDecodeTag(uint16_t coded_tag) {
+ uint32_t result = coded_tag;
+ result += static_cast<int8_t>(coded_tag);
+ return result >> 1;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Core mini parsing implementation:
+//////////////////////////////////////////////////////////////////////////////
+
+// Field lookup table layout:
+//
+// Because it consists of a series of variable-length segments, the lookuup
+// table is organized within an array of uint16_t, and each element is either
+// a uint16_t or a uint32_t stored little-endian as a pair of uint16_t.
+//
+// Its fundamental building block maps 16 contiguously ascending field numbers
+// to their locations within the field entry table:
+
+struct SkipEntry16 {
+ uint16_t skipmap;
+ uint16_t field_entry_offset;
+};
+
+// The skipmap is a bitfield of which of those field numbers do NOT have a
+// field entry. The lowest bit of the skipmap corresponds to the lowest of
+// the 16 field numbers, so if a proto had only fields 1, 2, 3, and 7, the
+// skipmap would contain 0b11111111'10111000.
+//
+// The field lookup table begins with a single 32-bit skipmap that maps the
+// field numbers 1 through 32. This is because the majority of proto
+// messages only contain fields numbered 1 to 32.
+//
+// The rest of the lookup table is a repeated series of
+// { 32-bit field #, #SkipEntry16s, {SkipEntry16...} }
+// That is, the next thing is a pair of uint16_t that form the next
+// lowest field number that the lookup table handles. If this number is -1,
+// that is the end of the table. Then there is a uint16_t that is
+// the number of contiguous SkipEntry16 entries that follow, and then of
+// course the SkipEntry16s themselves.
+
+// Originally developed and tested at https://godbolt.org/z/vbc7enYcf
+
+// Returns the address of the field for `tag` in the table's field entries.
+// Returns nullptr if the field was not found.
+const TcParseTableBase::FieldEntry* TcParser::FindFieldEntry(
+ const TcParseTableBase* table, uint32_t field_num) {
+ const FieldEntry* const field_entries = table->field_entries_begin();
+
+ uint32_t fstart = 1;
+ uint32_t adj_fnum = field_num - fstart;
+
+ if (PROTOBUF_PREDICT_TRUE(adj_fnum < 32)) {
+ uint32_t skipmap = table->skipmap32;
+ uint32_t skipbit = 1 << adj_fnum;
+ if (PROTOBUF_PREDICT_FALSE(skipmap & skipbit)) return nullptr;
+ skipmap &= skipbit - 1;
+#if (__GNUC__ || __clang__) && __POPCNT__
+ // Note: here and below, skipmap typically has very few set bits
+ // (31 in the worst case, but usually zero) so a loop isn't that
+ // bad, and a compiler-generated popcount is typically only
+ // worthwhile if the processor itself has hardware popcount support.
+ adj_fnum -= __builtin_popcount(skipmap);
+#else
+ while (skipmap) {
+ --adj_fnum;
+ skipmap &= skipmap - 1;
+ }
+#endif
+ auto* entry = field_entries + adj_fnum;
+ PROTOBUF_ASSUME(entry != nullptr);
+ return entry;
+ }
+ const uint16_t* lookup_table = table->field_lookup_begin();
+ for (;;) {
+#ifdef PROTOBUF_LITTLE_ENDIAN
+ memcpy(&fstart, lookup_table, sizeof(fstart));
+#else
+ fstart = lookup_table[0] | (lookup_table[1] << 16);
+#endif
+ lookup_table += sizeof(fstart) / sizeof(*lookup_table);
+ uint32_t num_skip_entries = *lookup_table++;
+ if (field_num < fstart) return nullptr;
+ adj_fnum = field_num - fstart;
+ uint32_t skip_num = adj_fnum / 16;
+ if (PROTOBUF_PREDICT_TRUE(skip_num < num_skip_entries)) {
+ // for each group of 16 fields we have:
+ // a bitmap of 16 bits
+ // a 16-bit field-entry offset for the first of them.
+ auto* skip_data = lookup_table + (adj_fnum / 16) * (sizeof(SkipEntry16) /
+ sizeof(uint16_t));
+ SkipEntry16 se = {skip_data[0], skip_data[1]};
+ adj_fnum &= 15;
+ uint32_t skipmap = se.skipmap;
+ uint16_t skipbit = 1 << adj_fnum;
+ if (PROTOBUF_PREDICT_FALSE(skipmap & skipbit)) return nullptr;
+ skipmap &= skipbit - 1;
+ adj_fnum += se.field_entry_offset;
+#if (__GNUC__ || __clang__) && __POPCNT__
+ adj_fnum -= __builtin_popcount(skipmap);
+#else
+ while (skipmap) {
+ --adj_fnum;
+ skipmap &= skipmap - 1;
+ }
+#endif
+ auto* entry = field_entries + adj_fnum;
+ PROTOBUF_ASSUME(entry != nullptr);
+ return entry;
+ }
+ lookup_table +=
+ num_skip_entries * (sizeof(SkipEntry16) / sizeof(*lookup_table));
+ }
+}
+
+// Field names are stored in a format of:
+//
+// 1) A table of name sizes, one byte each, from 1 to 255 per name.
+// `entries` is the size of this first table.
+// 1a) padding bytes, so the table of name sizes is a multiple of
+// eight bytes in length. They are zero.
+//
+// 2) All the names, concatenated, with neither separation nor termination.
+//
+// This is designed to be compact but not particularly fast to retrieve.
+// In particular, it takes O(n) to retrieve the name of the n'th field,
+// which is usually fine because most protos have fewer than 10 fields.
+static StringPiece FindName(const char* name_data, size_t entries,
+ size_t index) {
+ // The compiler unrolls these... if this isn't fast enough,
+ // there's an AVX version at https://godbolt.org/z/eojrjqzfr
+ // ARM-compatible version at https://godbolt.org/z/n5YT5Ee85
+
+ // The field name sizes are padded up to a multiple of 8, so we
+ // must pad them here.
+ size_t num_sizes = (entries + 7) & -8;
+ auto* uint8s = reinterpret_cast<const uint8_t*>(name_data);
+ size_t pos = std::accumulate(uint8s, uint8s + index, num_sizes);
+ size_t size = name_data[index];
+ auto* start = &name_data[pos];
+ return {start, size};
+}
+
+StringPiece TcParser::MessageName(const TcParseTableBase* table) {
+ return FindName(table->name_data(), table->num_field_entries + 1, 0);
+}
+
+StringPiece TcParser::FieldName(const TcParseTableBase* table,
+ const FieldEntry* field_entry) {
+ const FieldEntry* const field_entries = table->field_entries_begin();
+ auto field_index = static_cast<size_t>(field_entry - field_entries);
+ return FindName(table->name_data(), table->num_field_entries + 1,
+ field_index + 1);
+}
+
+const char* TcParser::MiniParse(PROTOBUF_TC_PARAM_DECL) {
+ uint32_t tag;
+ ptr = ReadTagInlined(ptr, &tag);
+ if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr;
+
+ auto* entry = FindFieldEntry(table, tag >> 3);
+ if (entry == nullptr) {
+ data.data = tag;
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+
+ // The handler may need the tag and the entry to resolve fallback logic. Both
+ // of these are 32 bits, so pack them into (the 64-bit) `data`. Since we can't
+ // pack the entry pointer itself, just pack its offset from `table`.
+ uint64_t entry_offset = reinterpret_cast<const char*>(entry) -
+ reinterpret_cast<const char*>(table);
+ data.data = entry_offset << 32 | tag;
+
+ using field_layout::FieldKind;
+ auto field_type = entry->type_card & FieldKind::kFkMask;
+ switch (field_type) {
+ case FieldKind::kFkNone:
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ case FieldKind::kFkVarint:
+ PROTOBUF_MUSTTAIL return MpVarint(PROTOBUF_TC_PARAM_PASS);
+ case FieldKind::kFkPackedVarint:
+ PROTOBUF_MUSTTAIL return MpPackedVarint(PROTOBUF_TC_PARAM_PASS);
+ case FieldKind::kFkFixed:
+ PROTOBUF_MUSTTAIL return MpFixed(PROTOBUF_TC_PARAM_PASS);
+ case FieldKind::kFkPackedFixed:
+ PROTOBUF_MUSTTAIL return MpPackedFixed(PROTOBUF_TC_PARAM_PASS);
+ case FieldKind::kFkString:
+ PROTOBUF_MUSTTAIL return MpString(PROTOBUF_TC_PARAM_PASS);
+ case FieldKind::kFkMessage:
+ PROTOBUF_MUSTTAIL return MpMessage(PROTOBUF_TC_PARAM_PASS);
+ case FieldKind::kFkMap:
+ PROTOBUF_MUSTTAIL return MpMap(PROTOBUF_TC_PARAM_PASS);
+ default:
+ return Error(PROTOBUF_TC_PARAM_PASS);
+ }
+}
+
+namespace {
+
+// Offset returns the address `offset` bytes after `base`.
+inline void* Offset(void* base, uint32_t offset) {
+ return static_cast<uint8_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
+
+//////////////////////////////////////////////////////////////////////////////
+// Message fields
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename TagType, bool group_coding>
+inline PROTOBUF_ALWAYS_INLINE
+const char* TcParser::SingularParseMessageAuxImpl(PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+ }
+ auto saved_tag = UnalignedLoad<TagType>(ptr);
+ ptr += sizeof(TagType);
+ hasbits |= (uint64_t{1} << data.hasbit_idx());
+ SyncHasbits(msg, hasbits, table);
+ auto& field = RefAt<MessageLite*>(msg, data.offset());
+ if (field == nullptr) {
+ const MessageLite* default_instance =
+ table->field_aux(data.aux_idx())->message_default;
+ field = default_instance->New(ctx->data().arena);
+ }
+ if (group_coding) {
+ return ctx->ParseGroup(field, ptr, FastDecodeTag(saved_tag));
+ }
+ return ctx->ParseMessage(field, ptr);
+}
+
+const char* TcParser::FastMS1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl<uint8_t, false>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::FastMS2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl<uint16_t, false>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::FastGS1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl<uint8_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::FastGS2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl<uint16_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+template <typename TagType, bool group_coding>
+inline PROTOBUF_ALWAYS_INLINE
+const char* TcParser::RepeatedParseMessageAuxImpl(PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+ }
+ auto saved_tag = UnalignedLoad<TagType>(ptr);
+ ptr += sizeof(TagType);
+ SyncHasbits(msg, hasbits, table);
+ const MessageLite* default_instance =
+ table->field_aux(data.aux_idx())->message_default;
+ auto& field = RefAt<RepeatedPtrFieldBase>(msg, data.offset());
+ MessageLite* submsg =
+ field.Add<GenericTypeHandler<MessageLite>>(default_instance);
+ if (group_coding) {
+ return ctx->ParseGroup(submsg, ptr, FastDecodeTag(saved_tag));
+ }
+ return ctx->ParseMessage(submsg, ptr);
+}
+
+const char* TcParser::FastMR1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl<uint8_t, false>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::FastMR2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl<uint16_t, false>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::FastGR1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl<uint8_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::FastGR2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl<uint16_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Fixed fields
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename LayoutType, typename TagType>
+PROTOBUF_ALWAYS_INLINE const char* TcParser::SingularFixed(
+ PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+ }
+ ptr += sizeof(TagType); // Consume tag
+ hasbits |= (uint64_t{1} << data.hasbit_idx());
+ RefAt<LayoutType>(msg, data.offset()) = UnalignedLoad<LayoutType>(ptr);
+ ptr += sizeof(LayoutType);
+ PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::FastF32S1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularFixed<uint32_t, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastF32S2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularFixed<uint32_t, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastF64S1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularFixed<uint64_t, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastF64S2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularFixed<uint64_t, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+template <typename LayoutType, typename TagType>
+PROTOBUF_ALWAYS_INLINE 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 {
+ PROTOBUF_MUSTTAIL return MiniParse(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);
+ elem[idx++] = UnalignedLoad<LayoutType>(ptr);
+ 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);
+}
+
+const char* TcParser::FastF32R1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedFixed<uint32_t, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastF32R2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedFixed<uint32_t, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastF64R1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedFixed<uint64_t, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastF64R2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedFixed<uint64_t, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+// Note: some versions of GCC will fail with error "function not inlinable" if
+// corecursive functions are both marked with PROTOBUF_ALWAYS_INLINE (Clang
+// accepts this). We can still apply the attribute to one of the two functions,
+// just not both (so we do mark the Repeated variant as always inlined). This
+// also applies to PackedVarint, below.
+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 {
+ PROTOBUF_MUSTTAIL return MiniParse(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));
+}
+
+const char* TcParser::FastF32P1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedFixed<uint32_t, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastF32P2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedFixed<uint32_t, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastF64P1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedFixed<uint64_t, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastF64P2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedFixed<uint64_t, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Varint fields
+//////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+// Shift "byte" left by n * 7 bits, filling vacated bits with ones.
+template <int n>
+inline PROTOBUF_ALWAYS_INLINE uint64_t
+shift_left_fill_with_ones(uint64_t byte, uint64_t ones) {
+ return (byte << (n * 7)) | (ones >> (64 - (n * 7)));
+}
+
+// Shift "byte" left by n * 7 bits, filling vacated bits with ones, and
+// put the new value in res. Return whether the result was negative.
+template <int n>
+inline PROTOBUF_ALWAYS_INLINE bool shift_left_fill_with_ones_was_negative(
+ uint64_t byte, uint64_t ones, int64_t& res) {
+#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.
+ bool sign_bit;
+ asm("shldq %3, %2, %1"
+ : "=@ccs"(sign_bit), "+r"(byte)
+ : "r"(ones), "i"(n * 7));
+ res = byte;
+ return sign_bit;
+#else
+ // Generic fallback:
+ res = (byte << (n * 7)) | (ones >> (64 - (n * 7)));
+ return static_cast<int64_t>(res) < 0;
+#endif
+}
+
+inline PROTOBUF_ALWAYS_INLINE std::pair<const char*, uint64_t>
+Parse64FallbackPair(const char* p, int64_t 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);
+ uint64_t ones = res1; // save the high 1 bits from res1 (input to SHLD)
+ int64_t res2, res3; // accumulated result chunks
+
+ if (!shift_left_fill_with_ones_was_negative<1>(ptr[1], ones, res2))
+ goto done2;
+ if (!shift_left_fill_with_ones_was_negative<2>(ptr[2], ones, res3))
+ goto done3;
+
+ // For the remainder of the chunks, check the sign of the AND result.
+ res1 &= shift_left_fill_with_ones<3>(ptr[3], ones);
+ if (res1 >= 0) goto done4;
+ res2 &= shift_left_fill_with_ones<4>(ptr[4], ones);
+ if (res2 >= 0) goto done5;
+ res3 &= shift_left_fill_with_ones<5>(ptr[5], ones);
+ if (res3 >= 0) goto done6;
+ res1 &= shift_left_fill_with_ones<6>(ptr[6], ones);
+ if (res1 >= 0) goto done7;
+ res2 &= shift_left_fill_with_ones<7>(ptr[7], ones);
+ if (res2 >= 0) goto done8;
+ res3 &= shift_left_fill_with_ones<8>(ptr[8], ones);
+ if (res3 >= 0) goto done9;
+
+ // 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.
+ if (PROTOBUF_PREDICT_TRUE(ptr[9] == 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 (ptr[9] == 0) {
+#if defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(__x86_64__)
+ // Use a small instruction since this is an uncommon code path.
+ asm("btcq $63,%0" : "+r"(res3));
+#else
+ res3 ^= static_cast<uint64_t>(1) << 63;
+#endif
+ 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};
+
+done2:
+ return {p + 2, res1 & res2};
+done3:
+ return {p + 3, res1 & res2 & res3};
+done4:
+ return {p + 4, res1 & res2 & res3};
+done5:
+ return {p + 5, res1 & res2 & res3};
+done6:
+ return {p + 6, res1 & res2 & res3};
+done7:
+ return {p + 7, res1 & res2 & res3};
+done8:
+ return {p + 8, res1 & res2 & res3};
+done9:
+ return {p + 9, res1 & res2 & res3};
+done10:
+ return {p + 10, res1 & res2 & res3};
+}
+
+inline PROTOBUF_ALWAYS_INLINE const char* ParseVarint(const char* p,
+ uint64_t* value) {
+ int64_t 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, bool zigzag = false>
+inline FieldType ZigZagDecodeHelper(uint64_t value) {
+ return static_cast<FieldType>(value);
+}
+
+template <>
+inline int32_t ZigZagDecodeHelper<int32_t, true>(uint64_t value) {
+ return WireFormatLite::ZigZagDecode32(value);
+}
+
+template <>
+inline int64_t ZigZagDecodeHelper<int64_t, true>(uint64_t value) {
+ return WireFormatLite::ZigZagDecode64(value);
+}
+
+bool EnumIsValidAux(int32_t val, uint16_t xform_val,
+ TcParseTableBase::FieldAux aux) {
+ if (xform_val == field_layout::kTvRange) {
+ auto lo = aux.enum_range.start;
+ return lo <= val && val < (lo + aux.enum_range.length);
+ }
+ return aux.enum_validator(val);
+}
+
+} // namespace
+
+template <typename FieldType, typename TagType, bool zigzag>
+PROTOBUF_ALWAYS_INLINE const char* TcParser::SingularVarint(
+ PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+ }
+ ptr += sizeof(TagType); // Consume tag
+ hasbits |= (uint64_t{1} << data.hasbit_idx());
+
+ // clang isn't smart enough to be able to only conditionally save
+ // registers to the stack, so we turn the integer-greater-than-128
+ // case into a separate routine.
+ if (PROTOBUF_PREDICT_FALSE(static_cast<int8_t>(*ptr) < 0)) {
+ PROTOBUF_MUSTTAIL return SingularVarBigint<FieldType, TagType, zigzag>(
+ PROTOBUF_TC_PARAM_PASS);
+ }
+
+ RefAt<FieldType>(msg, data.offset()) =
+ ZigZagDecodeHelper<FieldType, zigzag>(static_cast<uint8_t>(*ptr++));
+ PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_PASS);
+}
+
+template <typename FieldType, typename TagType, bool zigzag>
+PROTOBUF_NOINLINE const char* TcParser::SingularVarBigint(
+ PROTOBUF_TC_PARAM_DECL) {
+ // For some reason clang wants to save 5 registers to the stack here,
+ // but we only need four for this code, so save the data we don't need
+ // to the stack. Happily, saving them this way uses regular store
+ // instructions rather than PUSH/POP, which saves time at the cost of greater
+ // code size, but for this heavily-used piece of code, that's fine.
+ struct Spill {
+ uint64_t field_data;
+ ::google::protobuf::MessageLite* msg;
+ const ::google::protobuf::internal::TcParseTableBase* table;
+ uint64_t hasbits;
+ };
+ volatile Spill spill = {data.data, msg, table, hasbits};
+
+ uint64_t tmp;
+ PROTOBUF_ASSUME(static_cast<int8_t>(*ptr) < 0);
+ ptr = ParseVarint(ptr, &tmp);
+
+ data.data = spill.field_data;
+ msg = spill.msg;
+ table = spill.table;
+ hasbits = spill.hasbits;
+
+ if (PROTOBUF_PREDICT_FALSE(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);
+}
+
+const char* TcParser::FastV8S1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularVarint<bool, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV8S2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularVarint<bool, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV32S1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularVarint<uint32_t, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV32S2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularVarint<uint32_t, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV64S1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularVarint<uint64_t, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV64S2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularVarint<uint64_t, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::FastZ32S1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularVarint<int32_t, uint8_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastZ32S2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularVarint<int32_t, uint16_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastZ64S1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularVarint<int64_t, uint8_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastZ64S2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularVarint<int64_t, uint16_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+template <typename FieldType, typename TagType, bool zigzag>
+PROTOBUF_ALWAYS_INLINE 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 {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+ }
+ }
+ auto& field = RefAt<RepeatedField<FieldType>>(msg, data.offset());
+ auto expected_tag = UnalignedLoad<TagType>(ptr);
+ do {
+ ptr += sizeof(TagType);
+ uint64_t 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);
+}
+
+const char* TcParser::FastV8R1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedVarint<bool, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV8R2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedVarint<bool, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV32R1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedVarint<uint32_t, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV32R2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedVarint<uint32_t, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV64R1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedVarint<uint64_t, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV64R2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedVarint<uint64_t, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::FastZ32R1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedVarint<int32_t, uint8_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastZ32R2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedVarint<int32_t, uint16_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastZ64R1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedVarint<int64_t, uint8_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastZ64R2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedVarint<int64_t, uint16_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+// See comment on PackedFixed for why this is not PROTOBUF_ALWAYS_INLINE.
+template <typename FieldType, typename TagType, bool zigzag>
+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 {
+ PROTOBUF_MUSTTAIL return MiniParse(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](uint64_t varint) {
+ FieldType val;
+ if (zigzag) {
+ if (sizeof(FieldType) == 8) {
+ val = WireFormatLite::ZigZagDecode64(varint);
+ } else {
+ val = WireFormatLite::ZigZagDecode32(varint);
+ }
+ } else {
+ val = varint;
+ }
+ field->Add(val);
+ });
+}
+
+const char* TcParser::FastV8P1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedVarint<bool, uint8_t>(PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV8P2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedVarint<bool, uint16_t>(PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV32P1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedVarint<uint32_t, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV32P2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedVarint<uint32_t, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV64P1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedVarint<uint64_t, uint8_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastV64P2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedVarint<uint64_t, uint16_t>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::FastZ32P1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedVarint<int32_t, uint8_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastZ32P2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedVarint<int32_t, uint16_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastZ64P1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedVarint<int64_t, uint8_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastZ64P2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return PackedVarint<int64_t, uint16_t, true>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Enum fields
+//////////////////////////////////////////////////////////////////////////////
+
+PROTOBUF_NOINLINE const char* TcParser::FastUnknownEnumFallback(
+ PROTOBUF_TC_PARAM_DECL) {
+ (void)msg;
+ (void)ctx;
+ (void)hasbits;
+
+ // If we know we want to put this field directly into the unknown field set,
+ // then we can skip the call to MiniParse and directly call table->fallback.
+ // However, we first have to update `data` to contain the decoded tag.
+ uint32_t tag;
+ ptr = ReadTag(ptr, &tag);
+ if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) {
+ return Error(PROTOBUF_TC_PARAM_PASS);
+ }
+ data.data = tag;
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+}
+
+template <typename TagType, uint16_t xform_val>
+PROTOBUF_ALWAYS_INLINE const char* TcParser::SingularEnum(
+ PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+ }
+ const char* ptr2 = ptr; // Save for unknown enum case
+ ptr += sizeof(TagType); // Consume tag
+ uint64_t tmp;
+ ptr = ParseVarint(ptr, &tmp);
+ if (ptr == nullptr) {
+ return Error(PROTOBUF_TC_PARAM_PASS);
+ }
+ const TcParseTableBase::FieldAux aux = *table->field_aux(data.aux_idx());
+ if (PROTOBUF_PREDICT_FALSE(
+ !EnumIsValidAux(static_cast<int32_t>(tmp), xform_val, aux))) {
+ ptr = ptr2;
+ PROTOBUF_MUSTTAIL return FastUnknownEnumFallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ hasbits |= (uint64_t{1} << data.hasbit_idx());
+ RefAt<int32_t>(msg, data.offset()) = tmp;
+ PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::FastErS1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularEnum<uint8_t, field_layout::kTvRange>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastErS2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularEnum<uint16_t, field_layout::kTvRange>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastEvS1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularEnum<uint8_t, field_layout::kTvEnum>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastEvS2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularEnum<uint16_t, field_layout::kTvEnum>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+template <typename TagType, uint16_t xform_val>
+PROTOBUF_ALWAYS_INLINE const char* TcParser::RepeatedEnum(
+ PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ InvertPacked<WireFormatLite::WIRETYPE_VARINT>(data);
+ if (data.coded_tag<TagType>() == 0) {
+ // Packed parsing is handled by generated fallback.
+ PROTOBUF_MUSTTAIL return FastUnknownEnumFallback(PROTOBUF_TC_PARAM_PASS);
+ } else {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+ }
+ }
+ auto& field = RefAt<RepeatedField<int32_t>>(msg, data.offset());
+ auto expected_tag = UnalignedLoad<TagType>(ptr);
+ const TcParseTableBase::FieldAux aux = *table->field_aux(data.aux_idx());
+ do {
+ const char* ptr2 = ptr; // save for unknown enum case
+ ptr += sizeof(TagType);
+ uint64_t tmp;
+ ptr = ParseVarint(ptr, &tmp);
+ if (ptr == nullptr) {
+ return Error(PROTOBUF_TC_PARAM_PASS);
+ }
+ if (PROTOBUF_PREDICT_FALSE(
+ !EnumIsValidAux(static_cast<int32_t>(tmp), xform_val, aux))) {
+ // We can avoid duplicate work in MiniParse by directly calling
+ // table->fallback.
+ ptr = ptr2;
+ PROTOBUF_MUSTTAIL return FastUnknownEnumFallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ field.Add(static_cast<int32_t>(tmp));
+ if (!ctx->DataAvailable(ptr)) {
+ break;
+ }
+ } while (UnalignedLoad<TagType>(ptr) == expected_tag);
+ return ToParseLoop(PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::FastErR1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedEnum<uint8_t, field_layout::kTvRange>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastErR2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedEnum<uint16_t, field_layout::kTvRange>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastEvR1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedEnum<uint8_t, field_layout::kTvEnum>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastEvR2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedEnum<uint16_t, field_layout::kTvEnum>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// String/bytes fields
+//////////////////////////////////////////////////////////////////////////////
+
+// Defined in wire_format_lite.cc
+void PrintUTF8ErrorLog(StringPiece message_name,
+ StringPiece field_name, const char* operation_str,
+ bool emit_stacktrace);
+
+void TcParser::ReportFastUtf8Error(uint32_t decoded_tag,
+ const TcParseTableBase* table) {
+ uint32_t field_num = decoded_tag >> 3;
+ const auto* entry = FindFieldEntry(table, field_num);
+ PrintUTF8ErrorLog(MessageName(table), FieldName(table, entry), "parsing",
+ false);
+}
+
+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->MutableNoCopy(nullptr));
+}
+
+} // namespace
+
+template <typename TagType, TcParser::Utf8Type utf8>
+PROTOBUF_ALWAYS_INLINE const char* TcParser::SingularString(
+ PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+ }
+ auto saved_tag = UnalignedLoad<TagType>(ptr);
+ ptr += sizeof(TagType);
+ hasbits |= (uint64_t{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);
+ }
+ ReportFastUtf8Error(FastDecodeTag(saved_tag), table);
+ return utf8 == kUtf8 ? Error(PROTOBUF_TC_PARAM_PASS)
+ : ToParseLoop(PROTOBUF_TC_PARAM_PASS);
+ }
+}
+
+const char* TcParser::FastBS1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularString<uint8_t, kNoUtf8>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastBS2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularString<uint16_t, kNoUtf8>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastSS1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularString<uint8_t, kUtf8ValidateOnly>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastSS2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularString<uint16_t, kUtf8ValidateOnly>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastUS1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularString<uint8_t, kUtf8>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastUS2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return SingularString<uint16_t, kUtf8>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+// Inlined string variants:
+
+const char* TcParser::FastBiS1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastBiS2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastSiS1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastSiS2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastUiS1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastUiS2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+}
+
+template <typename TagType, TcParser::Utf8Type utf8>
+PROTOBUF_ALWAYS_INLINE const char* TcParser::RepeatedString(
+ PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_PASS);
+ }
+ auto expected_tag = UnalignedLoad<TagType>(ptr);
+ auto& field = RefAt<RepeatedPtrField<std::string>>(msg, data.offset());
+ do {
+ ptr += sizeof(TagType);
+ std::string* str = field.Add();
+ ptr = InlineGreedyStringParser(str, ptr, ctx);
+ if (ptr == nullptr) {
+ return Error(PROTOBUF_TC_PARAM_PASS);
+ }
+ switch (utf8) {
+ case kNoUtf8:
+#ifdef NDEBUG
+ case kUtf8ValidateOnly:
+#endif
+ break;
+ default:
+ if (PROTOBUF_PREDICT_TRUE(IsStructurallyValidUTF8(*str))) {
+ break;
+ }
+ ReportFastUtf8Error(FastDecodeTag(expected_tag), table);
+ if (utf8 == kUtf8) return Error(PROTOBUF_TC_PARAM_PASS);
+ break;
+ }
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (UnalignedLoad<TagType>(ptr) == expected_tag);
+ return ToParseLoop(PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::FastBR1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedString<uint8_t, kNoUtf8>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastBR2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedString<uint16_t, kNoUtf8>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastSR1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedString<uint8_t, kUtf8ValidateOnly>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastSR2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedString<uint16_t, kUtf8ValidateOnly>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastUR1(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedString<uint8_t, kUtf8>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+const char* TcParser::FastUR2(PROTOBUF_TC_PARAM_DECL) {
+ PROTOBUF_MUSTTAIL return RepeatedString<uint16_t, kUtf8>(
+ PROTOBUF_TC_PARAM_PASS);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Mini parsing
+//////////////////////////////////////////////////////////////////////////////
+
+namespace {
+inline void SetHas(const TcParseTableBase* table, const FieldEntry& entry,
+ MessageLite* msg, uint64_t& hasbits) {
+ int32_t has_idx = entry.has_idx;
+ if (has_idx < 32) {
+ hasbits |= uint64_t{1} << has_idx;
+ } else {
+ auto* hasblocks = &TcParser::RefAt<uint32_t>(msg, table->has_bits_offset);
+#if defined(__x86_64__) && defined(__GNUC__)
+ asm("bts %1, %0\n" : "+m"(*hasblocks) : "r"(has_idx));
+#else
+ auto& hasblock = hasblocks[has_idx / 32];
+ hasblock |= uint32_t{1} << (has_idx % 32);
+#endif
+ }
+}
+} // namespace
+
+// Destroys any existing oneof union member (if necessary). Returns true if the
+// caller is responsible for initializing the object, or false if the field
+// already has the desired case.
+bool TcParser::ChangeOneof(const TcParseTableBase* table,
+ const TcParseTableBase::FieldEntry& entry,
+ uint32_t field_num, ParseContext* ctx,
+ MessageLite* msg) {
+ // The _oneof_case_ array offset is stored in the first aux entry.
+ uint32_t oneof_case_offset = table->field_aux(0u)->offset;
+ // The _oneof_case_ array index is stored in the has-bit index.
+ uint32_t* oneof_case =
+ &TcParser::RefAt<uint32_t>(msg, oneof_case_offset) + entry.has_idx;
+ uint32_t current_case = *oneof_case;
+ *oneof_case = field_num;
+
+ if (current_case == 0) {
+ // If the member is empty, we don't have anything to clear. Caller is
+ // responsible for creating a new member object.
+ return true;
+ }
+ if (current_case == field_num) {
+ // If the member is already active, then it should be merged. We're done.
+ return false;
+ }
+ // Look up the value that is already stored, and dispose of it if necessary.
+ const FieldEntry* current_entry = FindFieldEntry(table, current_case);
+ uint16_t current_kind = current_entry->type_card & field_layout::kFkMask;
+ uint16_t current_rep = current_entry->type_card & field_layout::kRepMask;
+ if (current_kind == field_layout::kFkString) {
+ switch (current_rep) {
+ case field_layout::kRepAString: {
+ auto& field = RefAt<ArenaStringPtr>(msg, current_entry->offset);
+ field.Destroy();
+ break;
+ }
+ case field_layout::kRepSString:
+ case field_layout::kRepIString:
+ default:
+ GOOGLE_LOG(DFATAL) << "string rep not handled: "
+ << (current_rep >> field_layout::kRepShift);
+ return true;
+ }
+ } else if (current_kind == field_layout::kFkMessage) {
+ switch (current_rep) {
+ case field_layout::kRepMessage:
+ case field_layout::kRepGroup:
+ case field_layout::kRepIWeak: {
+ auto& field = RefAt<MessageLite*>(msg, current_entry->offset);
+ if (!ctx->data().arena) {
+ delete field;
+ }
+ break;
+ }
+ default:
+ GOOGLE_LOG(DFATAL) << "message rep not handled: "
+ << (current_rep >> field_layout::kRepShift);
+ break;
+ }
+ }
+ return true;
+}
+
+const char* TcParser::MpFixed(PROTOBUF_TC_PARAM_DECL) {
+ const auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
+ const uint16_t type_card = entry.type_card;
+ const uint16_t card = type_card & field_layout::kFcMask;
+
+ // Check for repeated parsing (wiretype fallback is handled there):
+ if (card == field_layout::kFcRepeated) {
+ PROTOBUF_MUSTTAIL return MpRepeatedFixed(PROTOBUF_TC_PARAM_PASS);
+ }
+ // Check for mismatched wiretype:
+ const uint16_t rep = type_card & field_layout::kRepMask;
+ const uint32_t decoded_wiretype = data.tag() & 7;
+ if (rep == field_layout::kRep64Bits) {
+ if (decoded_wiretype != WireFormatLite::WIRETYPE_FIXED64) {
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ } else {
+ GOOGLE_DCHECK_EQ(rep, static_cast<uint16_t>(field_layout::kRep32Bits));
+ if (decoded_wiretype != WireFormatLite::WIRETYPE_FIXED32) {
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ }
+ // Set the field present:
+ if (card == field_layout::kFcOptional) {
+ SetHas(table, entry, msg, hasbits);
+ } else if (card == field_layout::kFcOneof) {
+ ChangeOneof(table, entry, data.tag() >> 3, ctx, msg);
+ }
+ // Copy the value:
+ if (rep == field_layout::kRep64Bits) {
+ RefAt<uint64_t>(msg, entry.offset) = UnalignedLoad<uint64_t>(ptr);
+ ptr += sizeof(uint64_t);
+ } else {
+ RefAt<uint32_t>(msg, entry.offset) = UnalignedLoad<uint32_t>(ptr);
+ ptr += sizeof(uint32_t);
+ }
+ PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::MpRepeatedFixed(PROTOBUF_TC_PARAM_DECL) {
+ const auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
+ const uint32_t decoded_tag = data.tag();
+ const uint32_t decoded_wiretype = decoded_tag & 7;
+
+ // Check for packed repeated fallback:
+ if (decoded_wiretype == WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ PROTOBUF_MUSTTAIL return MpPackedFixed(PROTOBUF_TC_PARAM_PASS);
+ }
+
+ const uint16_t type_card = entry.type_card;
+ const uint16_t rep = type_card & field_layout::kRepMask;
+ if (rep == field_layout::kRep64Bits) {
+ if (decoded_wiretype != WireFormatLite::WIRETYPE_FIXED64) {
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ auto& field = RefAt<RepeatedField<uint64_t>>(msg, entry.offset);
+ constexpr auto size = sizeof(uint64_t);
+ const char* ptr2 = ptr;
+ uint32_t next_tag;
+ do {
+ ptr = ptr2;
+ *field.Add() = UnalignedLoad<uint64_t>(ptr);
+ ptr += size;
+ if (!ctx->DataAvailable(ptr)) break;
+ ptr2 = ReadTag(ptr, &next_tag);
+ } while (next_tag == decoded_tag);
+ } else {
+ GOOGLE_DCHECK_EQ(rep, static_cast<uint16_t>(field_layout::kRep32Bits));
+ if (decoded_wiretype != WireFormatLite::WIRETYPE_FIXED32) {
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ auto& field = RefAt<RepeatedField<uint32_t>>(msg, entry.offset);
+ constexpr auto size = sizeof(uint32_t);
+ const char* ptr2 = ptr;
+ uint32_t next_tag;
+ do {
+ ptr = ptr2;
+ *field.Add() = UnalignedLoad<uint32_t>(ptr);
+ ptr += size;
+ if (!ctx->DataAvailable(ptr)) break;
+ ptr2 = ReadTag(ptr, &next_tag);
+ } while (next_tag == decoded_tag);
+ }
+
+ PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::MpPackedFixed(PROTOBUF_TC_PARAM_DECL) {
+ const auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
+ const uint16_t type_card = entry.type_card;
+ const uint32_t decoded_wiretype = data.tag() & 7;
+
+ // Check for non-packed repeated fallback:
+ if (decoded_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ PROTOBUF_MUSTTAIL return MpRepeatedFixed(PROTOBUF_TC_PARAM_PASS);
+ }
+
+ // Since ctx->ReadPackedFixed does not use TailCall<> or Return<>, sync any
+ // pending hasbits now:
+ SyncHasbits(msg, hasbits, table);
+
+ int size = ReadSize(&ptr);
+ uint16_t rep = type_card & field_layout::kRepMask;
+ if (rep == field_layout::kRep64Bits) {
+ auto& field = RefAt<RepeatedField<uint64_t>>(msg, entry.offset);
+ ptr = ctx->ReadPackedFixed(ptr, size, &field);
+ } else {
+ GOOGLE_DCHECK_EQ(rep, static_cast<uint16_t>(field_layout::kRep32Bits));
+ auto& field = RefAt<RepeatedField<uint32_t>>(msg, entry.offset);
+ ptr = ctx->ReadPackedFixed(ptr, size, &field);
+ }
+
+ if (ptr == nullptr) {
+ return Error(PROTOBUF_TC_PARAM_PASS);
+ }
+ PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::MpVarint(PROTOBUF_TC_PARAM_DECL) {
+ const auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
+ const uint16_t type_card = entry.type_card;
+ const uint16_t card = type_card & field_layout::kFcMask;
+
+ // Check for repeated parsing:
+ if (card == field_layout::kFcRepeated) {
+ PROTOBUF_MUSTTAIL return MpRepeatedVarint(PROTOBUF_TC_PARAM_PASS);
+ }
+ // Check for wire type mismatch:
+ if ((data.tag() & 7) != WireFormatLite::WIRETYPE_VARINT) {
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ const uint16_t xform_val = type_card & field_layout::kTvMask;
+ const bool is_zigzag = xform_val == field_layout::kTvZigZag;
+ const bool is_validated_enum = xform_val & field_layout::kTvEnum;
+
+ // Parse the value:
+ const char* ptr2 = ptr; // save for unknown enum case
+ uint64_t tmp;
+ ptr = ParseVarint(ptr, &tmp);
+ if (ptr == nullptr) return Error(PROTOBUF_TC_PARAM_PASS);
+
+ // Transform and/or validate the value
+ uint16_t rep = type_card & field_layout::kRepMask;
+ if (rep == field_layout::kRep64Bits) {
+ if (is_zigzag) {
+ tmp = WireFormatLite::ZigZagDecode64(tmp);
+ }
+ } else if (rep == field_layout::kRep32Bits) {
+ if (is_validated_enum) {
+ if (!EnumIsValidAux(tmp, xform_val, *table->field_aux(&entry))) {
+ ptr = ptr2;
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ } else if (is_zigzag) {
+ tmp = WireFormatLite::ZigZagDecode32(static_cast<uint32_t>(tmp));
+ }
+ }
+
+ // Mark the field as present:
+ const bool is_oneof = card == field_layout::kFcOneof;
+ if (card == field_layout::kFcOptional) {
+ SetHas(table, entry, msg, hasbits);
+ } else if (is_oneof) {
+ ChangeOneof(table, entry, data.tag() >> 3, ctx, msg);
+ }
+
+ if (rep == field_layout::kRep64Bits) {
+ RefAt<uint64_t>(msg, entry.offset) = tmp;
+ } else if (rep == field_layout::kRep32Bits) {
+ RefAt<uint32_t>(msg, entry.offset) = static_cast<uint32_t>(tmp);
+ } else {
+ GOOGLE_DCHECK_EQ(rep, static_cast<uint16_t>(field_layout::kRep8Bits));
+ RefAt<bool>(msg, entry.offset) = static_cast<bool>(tmp);
+ }
+
+ PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::MpRepeatedVarint(PROTOBUF_TC_PARAM_DECL) {
+ const auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
+ auto type_card = entry.type_card;
+ const uint32_t decoded_tag = data.tag();
+ auto decoded_wiretype = decoded_tag & 7;
+
+ // Check for packed repeated fallback:
+ if (decoded_wiretype == WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ PROTOBUF_MUSTTAIL return MpPackedVarint(PROTOBUF_TC_PARAM_PASS);
+ }
+ // Check for wire type mismatch:
+ if (decoded_wiretype != WireFormatLite::WIRETYPE_VARINT) {
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ uint16_t xform_val = (type_card & field_layout::kTvMask);
+ const bool is_zigzag = xform_val == field_layout::kTvZigZag;
+ const bool is_validated_enum = xform_val & field_layout::kTvEnum;
+
+ uint16_t rep = type_card & field_layout::kRepMask;
+ if (rep == field_layout::kRep64Bits) {
+ auto& field = RefAt<RepeatedField<uint64_t>>(msg, entry.offset);
+ const char* ptr2 = ptr;
+ uint32_t next_tag;
+ do {
+ uint64_t tmp;
+ ptr = ParseVarint(ptr2, &tmp);
+ if (ptr == nullptr) return Error(PROTOBUF_TC_PARAM_PASS);
+ field.Add(is_zigzag ? WireFormatLite::ZigZagDecode64(tmp) : tmp);
+ if (!ctx->DataAvailable(ptr)) break;
+ ptr2 = ReadTag(ptr, &next_tag);
+ } while (next_tag == decoded_tag);
+ } else if (rep == field_layout::kRep32Bits) {
+ auto& field = RefAt<RepeatedField<uint32_t>>(msg, entry.offset);
+ const char* ptr2 = ptr;
+ uint32_t next_tag;
+ do {
+ uint64_t tmp;
+ ptr = ParseVarint(ptr2, &tmp);
+ if (ptr == nullptr) return Error(PROTOBUF_TC_PARAM_PASS);
+ if (is_validated_enum) {
+ if (!EnumIsValidAux(tmp, xform_val, *table->field_aux(&entry))) {
+ ptr = ptr2;
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ } else if (is_zigzag) {
+ tmp = WireFormatLite::ZigZagDecode32(tmp);
+ }
+ field.Add(tmp);
+ if (!ctx->DataAvailable(ptr)) break;
+ ptr2 = ReadTag(ptr, &next_tag);
+ } while (next_tag == decoded_tag);
+ } else {
+ GOOGLE_DCHECK_EQ(rep, static_cast<uint16_t>(field_layout::kRep8Bits));
+ auto& field = RefAt<RepeatedField<bool>>(msg, entry.offset);
+ const char* ptr2 = ptr;
+ uint32_t next_tag;
+ do {
+ uint64_t tmp;
+ ptr = ParseVarint(ptr2, &tmp);
+ if (ptr == nullptr) return Error(PROTOBUF_TC_PARAM_PASS);
+ field.Add(static_cast<bool>(tmp));
+ if (!ctx->DataAvailable(ptr)) break;
+ ptr2 = ReadTag(ptr, &next_tag);
+ } while (next_tag == decoded_tag);
+ }
+
+ PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::MpPackedVarint(PROTOBUF_TC_PARAM_DECL) {
+ const auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
+ auto type_card = entry.type_card;
+ auto decoded_wiretype = data.tag() & 7;
+
+ // Check for non-packed repeated fallback:
+ if (decoded_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ PROTOBUF_MUSTTAIL return MpRepeatedVarint(PROTOBUF_TC_PARAM_PASS);
+ }
+ uint16_t xform_val = (type_card & field_layout::kTvMask);
+ const bool is_zigzag = xform_val == field_layout::kTvZigZag;
+ const bool is_validated_enum = xform_val & field_layout::kTvEnum;
+ if (is_validated_enum) {
+ // TODO(b/206890171): handle enums
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+
+ // Since ctx->ReadPackedFixed does not use TailCall<> or Return<>, sync any
+ // pending hasbits now:
+ SyncHasbits(msg, hasbits, table);
+
+ uint16_t rep = type_card & field_layout::kRepMask;
+ if (rep == field_layout::kRep64Bits) {
+ auto* field = &RefAt<RepeatedField<uint64_t>>(msg, entry.offset);
+ return ctx->ReadPackedVarint(ptr, [field, is_zigzag](uint64_t value) {
+ field->Add(is_zigzag ? WireFormatLite::ZigZagDecode64(value) : value);
+ });
+ } else if (rep == field_layout::kRep32Bits) {
+ auto* field = &RefAt<RepeatedField<uint32_t>>(msg, entry.offset);
+ return ctx->ReadPackedVarint(ptr, [field, is_zigzag](uint64_t value) {
+ field->Add(is_zigzag ? WireFormatLite::ZigZagDecode32(
+ static_cast<uint32_t>(value))
+ : value);
+ });
+ } else {
+ GOOGLE_DCHECK_EQ(rep, static_cast<uint16_t>(field_layout::kRep8Bits));
+ auto* field = &RefAt<RepeatedField<bool>>(msg, entry.offset);
+ return ctx->ReadPackedVarint(
+ ptr, [field](uint64_t value) { field->Add(value); });
+ }
+
+ return Error(PROTOBUF_TC_PARAM_PASS);
+}
+
+bool TcParser::MpVerifyUtf8(StringPiece wire_bytes,
+ const TcParseTableBase* table,
+ const FieldEntry& entry, uint16_t xform_val) {
+ if (xform_val == field_layout::kTvUtf8) {
+ if (!IsStructurallyValidUTF8(wire_bytes)) {
+ PrintUTF8ErrorLog(MessageName(table), FieldName(table, &entry), "parsing",
+ false);
+ return false;
+ }
+ return true;
+ }
+#ifndef NDEBUG
+ if (xform_val == field_layout::kTvUtf8Debug) {
+ if (!IsStructurallyValidUTF8(wire_bytes)) {
+ PrintUTF8ErrorLog(MessageName(table), FieldName(table, &entry), "parsing",
+ false);
+ }
+ }
+#endif // NDEBUG
+ return true;
+}
+
+const char* TcParser::MpString(PROTOBUF_TC_PARAM_DECL) {
+ const auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
+ const uint16_t type_card = entry.type_card;
+ const uint16_t card = type_card & field_layout::kFcMask;
+ const uint32_t decoded_wiretype = data.tag() & 7;
+
+ if (decoded_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ if (card == field_layout::kFcRepeated) {
+ PROTOBUF_MUSTTAIL return MpRepeatedString(PROTOBUF_TC_PARAM_PASS);
+ }
+ const uint16_t xform_val = type_card & field_layout::kTvMask;
+ const uint16_t rep = type_card & field_layout::kRepMask;
+ if (rep == field_layout::kRepIString) {
+ // TODO(b/198211897): support InilnedStringField.
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+
+ // Mark the field as present:
+ const bool is_oneof = card == field_layout::kFcOneof;
+ bool need_init = false;
+ if (card == field_layout::kFcOptional) {
+ SetHas(table, entry, msg, hasbits);
+ } else if (is_oneof) {
+ need_init = ChangeOneof(table, entry, data.tag() >> 3, ctx, msg);
+ }
+
+ bool is_valid = false;
+ Arena* arena = ctx->data().arena;
+ switch (rep) {
+ case field_layout::kRepAString: {
+ auto& field = RefAt<ArenaStringPtr>(msg, entry.offset);
+ if (need_init) field.InitDefault();
+ if (arena) {
+ ptr = ctx->ReadArenaString(ptr, &field, arena);
+ } else {
+ std::string* str = field.MutableNoCopy(nullptr);
+ ptr = InlineGreedyStringParser(str, ptr, ctx);
+ }
+ if (!ptr) break;
+ is_valid = MpVerifyUtf8(field.Get(), table, entry, xform_val);
+ break;
+ }
+
+ case field_layout::kRepIString: {
+ break;
+ }
+ }
+
+ if (ptr == nullptr || !is_valid) {
+ return Error(PROTOBUF_TC_PARAM_PASS);
+ }
+ return ToParseLoop(PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::MpRepeatedString(PROTOBUF_TC_PARAM_DECL) {
+ const auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
+ const uint16_t type_card = entry.type_card;
+ const uint32_t decoded_tag = data.tag();
+ const uint32_t decoded_wiretype = decoded_tag & 7;
+
+ if (decoded_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+
+ const uint16_t rep = type_card & field_layout::kRepMask;
+ const uint16_t xform_val = type_card & field_layout::kTvMask;
+ switch (rep) {
+ case field_layout::kRepSString: {
+ auto& field = RefAt<RepeatedPtrField<std::string>>(msg, entry.offset);
+ const char* ptr2 = ptr;
+ uint32_t next_tag;
+ do {
+ ptr = ptr2;
+ std::string* str = field.Add();
+ ptr = InlineGreedyStringParser(str, ptr, ctx);
+ if (PROTOBUF_PREDICT_FALSE(
+ ptr == nullptr ||
+ !MpVerifyUtf8(*str, table, entry, xform_val))) {
+ return Error(PROTOBUF_TC_PARAM_PASS);
+ }
+ if (!ctx->DataAvailable(ptr)) break;
+ ptr2 = ReadTag(ptr, &next_tag);
+ } while (next_tag == decoded_tag);
+ break;
+ }
+
+#ifndef NDEBUG
+ default:
+ GOOGLE_LOG(FATAL) << "Unsupported repeated string rep: " << rep;
+ break;
+#endif
+ }
+
+ return ToParseLoop(PROTOBUF_TC_PARAM_PASS);
+}
+
+const char* TcParser::MpMessage(PROTOBUF_TC_PARAM_DECL) {
+ const auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
+ const uint16_t type_card = entry.type_card;
+ const uint16_t card = type_card & field_layout::kFcMask;
+
+ // Check for repeated parsing:
+ if (card == field_layout::kFcRepeated) {
+ PROTOBUF_MUSTTAIL return MpRepeatedMessage(PROTOBUF_TC_PARAM_PASS);
+ }
+
+ const uint32_t decoded_tag = data.tag();
+ const uint32_t decoded_wiretype = decoded_tag & 7;
+ const uint16_t rep = type_card & field_layout::kRepMask;
+ const bool is_group = rep == field_layout::kRepGroup;
+
+ // Validate wiretype:
+ switch (rep) {
+ case field_layout::kRepMessage:
+ if (decoded_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ goto fallback;
+ }
+ break;
+ case field_layout::kRepGroup:
+ if (decoded_wiretype != WireFormatLite::WIRETYPE_START_GROUP) {
+ goto fallback;
+ }
+ break;
+ default: {
+ fallback:
+ // Lazy and implicit weak fields are handled by generated code:
+ // TODO(b/210762816): support these.
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ }
+
+ const bool is_oneof = card == field_layout::kFcOneof;
+ bool need_init = false;
+ if (card == field_layout::kFcOptional) {
+ SetHas(table, entry, msg, hasbits);
+ } else if (is_oneof) {
+ need_init = ChangeOneof(table, entry, data.tag() >> 3, ctx, msg);
+ }
+ MessageLite*& field = RefAt<MessageLite*>(msg, entry.offset);
+ if (need_init || field == nullptr) {
+ const MessageLite* default_instance =
+ table->field_aux(&entry)->message_default;
+ field = default_instance->New(ctx->data().arena);
+ }
+ SyncHasbits(msg, hasbits, table);
+ if (is_group) {
+ return ctx->ParseGroup(field, ptr, decoded_tag);
+ }
+ return ctx->ParseMessage(field, ptr);
+}
+
+const char* TcParser::MpRepeatedMessage(PROTOBUF_TC_PARAM_DECL) {
+ const auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
+ const uint16_t type_card = entry.type_card;
+ GOOGLE_DCHECK_EQ(type_card & field_layout::kFcMask,
+ static_cast<uint16_t>(field_layout::kFcRepeated));
+ const uint32_t decoded_tag = data.tag();
+ const uint32_t decoded_wiretype = decoded_tag & 7;
+ const uint16_t rep = type_card & field_layout::kRepMask;
+ const bool is_group = rep == field_layout::kRepGroup;
+
+ // Validate wiretype:
+ switch (rep) {
+ case field_layout::kRepMessage:
+ if (decoded_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ goto fallback;
+ }
+ break;
+ case field_layout::kRepGroup:
+ if (decoded_wiretype != WireFormatLite::WIRETYPE_START_GROUP) {
+ goto fallback;
+ }
+ break;
+ default: {
+ fallback:
+ // Lazy and implicit weak fields are handled by generated code:
+ // TODO(b/210762816): support these.
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ }
+
+ SyncHasbits(msg, hasbits, table);
+ const MessageLite* default_instance =
+ table->field_aux(&entry)->message_default;
+ auto& field = RefAt<RepeatedPtrFieldBase>(msg, entry.offset);
+ MessageLite* value =
+ field.Add<GenericTypeHandler<MessageLite>>(default_instance);
+ if (is_group) {
+ return ctx->ParseGroup(value, ptr, decoded_tag);
+ }
+ return ctx->ParseMessage(value, ptr);
+}
+
+const char* TcParser::MpMap(PROTOBUF_TC_PARAM_DECL) {
+ const auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
+ (void)entry;
+ PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/toolkit/components/protobuf/src/google/protobuf/generated_message_util.cc b/toolkit/components/protobuf/src/google/protobuf/generated_message_util.cc
new file mode 100644
index 0000000000..cad12a3511
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/generated_message_util.cc
@@ -0,0 +1,409 @@
+// 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/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 std::string*>(s)->~basic_string();
+}
+
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
+ PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ExplicitlyConstructedArenaString
+ 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_PRIORITY1 static std::true_type init_empty_string =
+ (InitProtobufDefaultsSlow(), std::true_type{});
+
+size_t StringSpaceUsedExcludingSelfLong(const std::string& 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 int32_t Type;
+ static void Serialize(const void* ptr, io::CodedOutputStream* output) {
+ WireFormatLite::WriteInt32NoTag(Get<int32_t>(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 int32_t Type;
+ static void Serialize(const void* ptr, io::CodedOutputStream* output) {
+ WireFormatLite::WriteSInt32NoTag(Get<int32_t>(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 uint32_t Type;
+ static void Serialize(const void* ptr, io::CodedOutputStream* output) {
+ WireFormatLite::WriteUInt32NoTag(Get<uint32_t>(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 int64_t Type;
+ static void Serialize(const void* ptr, io::CodedOutputStream* output) {
+ WireFormatLite::WriteInt64NoTag(Get<int64_t>(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 int64_t Type;
+ static void Serialize(const void* ptr, io::CodedOutputStream* output) {
+ WireFormatLite::WriteSInt64NoTag(Get<int64_t>(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 uint64_t Type;
+ static void Serialize(const void* ptr, io::CodedOutputStream* output) {
+ WireFormatLite::WriteUInt64NoTag(Get<uint64_t>(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 uint32_t Type;
+ static void Serialize(const void* ptr, io::CodedOutputStream* output) {
+ WireFormatLite::WriteFixed32NoTag(Get<uint32_t>(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 uint64_t Type;
+ static void Serialize(const void* ptr, io::CodedOutputStream* output) {
+ WireFormatLite::WriteFixed64NoTag(Get<uint64_t>(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 int32_t Type;
+};
+template <>
+struct PrimitiveTypeHelper<WireFormatLite::TYPE_SFIXED64>
+ : PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED64> {
+ typedef int64_t 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 std::string 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> {};
+
+// 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(uint32_t tag, O* output) {
+ SerializeTo<WireFormatLite::TYPE_UINT32>(&tag, output);
+}
+
+template <typename O>
+void WriteLengthTo(uint32_t 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();
+}
+
+// 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];
+ }
+};
+
+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)
+
+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;
+}
+
+void ExtensionSerializer(const MessageLite* extendee, const uint8_t* ptr,
+ uint32_t offset, uint32_t tag, uint32_t has_offset,
+ io::CodedOutputStream* output) {
+ reinterpret_cast<const ExtensionSet*>(ptr + offset)
+ ->SerializeWithCachedSizes(extendee, tag, has_offset, output);
+}
+
+void UnknownFieldSerializerLite(const uint8_t* ptr, uint32_t offset,
+ uint32_t /*tag*/, uint32_t /*has_offset*/,
+ io::CodedOutputStream* output) {
+ output->WriteString(
+ reinterpret_cast<const InternalMetadata*>(ptr + offset)
+ ->unknown_fields<std::string>(&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::InternalGetOwningArena(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/toolkit/components/protobuf/src/google/protobuf/generated_message_util.h b/toolkit/components/protobuf/src/google/protobuf/generated_message_util.h
new file mode 100644
index 0000000000..71d15cdebc
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/generated_message_util.h
@@ -0,0 +1,214 @@
+// 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/stubs/once.h> // Add direct dep on port for pb.cc
+#include <google/protobuf/port.h>
+#include <google/protobuf/stubs/strutil.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/repeated_field.h>
+#include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/stubs/casts.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;
+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 std::string& 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, uint32_t hasbit) {
+ const uint32_t* has_bits_array = static_cast<const uint32_t*>(base);
+ return (has_bits_array[hasbit / 32] & (1u << (hasbit & 31))) != 0;
+}
+
+inline bool IsOneofPresent(const void* base, uint32_t offset, uint32_t tag) {
+ const uint32_t* oneof = reinterpret_cast<const uint32_t*>(
+ static_cast<const uint8_t*>(base) + offset);
+ return *oneof == tag >> 3;
+}
+
+typedef void (*SpecialSerializer)(const uint8_t* base, uint32_t offset,
+ uint32_t tag, uint32_t has_offset,
+ io::CodedOutputStream* output);
+
+PROTOBUF_EXPORT void ExtensionSerializer(const MessageLite* extendee,
+ const uint8_t* ptr, uint32_t offset,
+ uint32_t tag, uint32_t has_offset,
+ io::CodedOutputStream* output);
+PROTOBUF_EXPORT void UnknownFieldSerializerLite(const uint8_t* base,
+ uint32_t offset, uint32_t tag,
+ uint32_t 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 std::string destructor)
+inline void OnShutdownDestroyString(const std::string* 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/toolkit/components/protobuf/src/google/protobuf/has_bits.h b/toolkit/components/protobuf/src/google/protobuf/has_bits.h
new file mode 100644
index 0000000000..f8a45879f1
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/has_bits.h
@@ -0,0 +1,117 @@
+// 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>
+
+// Must be included last.
+#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 uint32_t& operator[](int index) {
+ return has_bits_[index];
+ }
+
+ PROTOBUF_NDEBUG_INLINE const uint32_t& 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:
+ uint32_t 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/toolkit/components/protobuf/src/google/protobuf/implicit_weak_message.cc b/toolkit/components/protobuf/src/google/protobuf/implicit_weak_message.cc
new file mode 100644
index 0000000000..27ed6b65d2
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/implicit_weak_message.cc
@@ -0,0 +1,72 @@
+// 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/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/parse_context.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 {
+
+const char* ImplicitWeakMessage::_InternalParse(const char* ptr,
+ ParseContext* ctx) {
+ return ctx->AppendString(ptr, data_);
+}
+
+struct ImplicitWeakMessageDefaultType {
+ constexpr ImplicitWeakMessageDefaultType()
+ : instance(ConstantInitialized{}) {}
+ ~ImplicitWeakMessageDefaultType() {}
+ union {
+ ImplicitWeakMessage instance;
+ };
+};
+
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ImplicitWeakMessageDefaultType
+ implicit_weak_message_default_instance;
+
+const ImplicitWeakMessage* ImplicitWeakMessage::default_instance() {
+ return reinterpret_cast<ImplicitWeakMessage*>(
+ &implicit_weak_message_default_instance);
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
diff --git a/toolkit/components/protobuf/src/google/protobuf/implicit_weak_message.h b/toolkit/components/protobuf/src/google/protobuf/implicit_weak_message.h
new file mode 100644
index 0000000000..b894ab4809
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/implicit_weak_message.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.
+
+#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
+
+// Must be included last.
+#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() : data_(new std::string) {}
+ explicit constexpr ImplicitWeakMessage(ConstantInitialized)
+ : data_(nullptr) {}
+ explicit ImplicitWeakMessage(Arena* arena)
+ : MessageLite(arena), data_(new std::string) {}
+
+ ~ImplicitWeakMessage() override {
+ // data_ will be null in the default instance, but we can safely call delete
+ // here because the default instance will never be destroyed.
+ delete data_;
+ }
+
+ static const ImplicitWeakMessage* default_instance();
+
+ std::string 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 {
+ const std::string* other_data =
+ static_cast<const ImplicitWeakMessage&>(other).data_;
+ if (other_data != nullptr) {
+ data_->append(*other_data);
+ }
+ }
+
+ const char* _InternalParse(const char* ptr, ParseContext* ctx) final;
+
+ size_t ByteSizeLong() const override {
+ return data_ == nullptr ? 0 : data_->size();
+ }
+
+ uint8_t* _InternalSerialize(uint8_t* target,
+ io::EpsCopyOutputStream* stream) const final {
+ if (data_ == nullptr) {
+ return target;
+ }
+ return stream->WriteRaw(data_->data(), static_cast<int>(data_->size()),
+ target);
+ }
+
+ int GetCachedSize() const override {
+ return data_ == nullptr ? 0 : static_cast<int>(data_->size());
+ }
+
+ typedef void InternalArenaConstructable_;
+
+ private:
+ // This std::string is allocated on the heap, but we use a raw pointer so that
+ // the default instance can be constant-initialized. In the const methods, we
+ // have to handle the possibility of data_ being null.
+ std::string* data_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImplicitWeakMessage);
+};
+
+struct ImplicitWeakMessageDefaultType;
+extern ImplicitWeakMessageDefaultType implicit_weak_message_default_instance;
+
+// 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/toolkit/components/protobuf/src/google/protobuf/inlined_string_field.cc b/toolkit/components/protobuf/src/google/protobuf/inlined_string_field.cc
new file mode 100644
index 0000000000..0c3e4766fd
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/inlined_string_field.cc
@@ -0,0 +1,118 @@
+// 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/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/parse_context.h>
+
+// clang-format off
+#include <google/protobuf/port_def.inc>
+// clang-format on
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+
+std::string* InlinedStringField::Mutable(const LazyString& /*default_value*/,
+ Arena* arena, bool donated,
+ uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ if (arena == nullptr || !donated) {
+ return UnsafeMutablePointer();
+ }
+ return MutableSlow(arena, donated, donating_states, mask, msg);
+}
+
+std::string* InlinedStringField::Mutable(Arena* arena, bool donated,
+ uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ if (arena == nullptr || !donated) {
+ return UnsafeMutablePointer();
+ }
+ return MutableSlow(arena, donated, donating_states, mask, msg);
+}
+
+std::string* InlinedStringField::MutableSlow(::google::protobuf::Arena* arena,
+ bool donated,
+ uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ (void)mask;
+ (void)msg;
+ return UnsafeMutablePointer();
+}
+
+void InlinedStringField::SetAllocated(const std::string* default_value,
+ std::string* value, Arena* arena,
+ bool donated, uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ (void)mask;
+ (void)msg;
+ SetAllocatedNoArena(default_value, value);
+}
+
+void InlinedStringField::Set(std::string&& value, Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask,
+ MessageLite* msg) {
+ (void)donating_states;
+ (void)mask;
+ (void)msg;
+ SetNoArena(std::move(value));
+}
+
+std::string* InlinedStringField::Release() {
+ auto* released = new std::string(std::move(*get_mutable()));
+ get_mutable()->clear();
+ return released;
+}
+
+std::string* InlinedStringField::Release(Arena* arena, bool donated) {
+ // We can not steal donated arena strings.
+ std::string* released = (arena != nullptr && donated)
+ ? new std::string(*get_mutable())
+ : new std::string(std::move(*get_mutable()));
+ get_mutable()->clear();
+ return released;
+}
+
+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/toolkit/components/protobuf/src/google/protobuf/inlined_string_field.h b/toolkit/components/protobuf/src/google/protobuf/inlined_string_field.h
new file mode 100644
index 0000000000..79e37d414b
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/inlined_string_field.h
@@ -0,0 +1,532 @@
+// 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/port.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/message_lite.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 std::string instance and exposes an API similar to
+// ArenaStringPtr's wrapping of a std::string* 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()) std::string(); }
+ // Add the dummy parameter just to make InlinedStringField(nullptr)
+ // unambiguous.
+ constexpr InlinedStringField(
+ const ExplicitlyConstructed<std::string>* /*default_value*/,
+ bool /*dummy*/)
+ : value_{} {}
+ explicit InlinedStringField(const std::string& default_value);
+ explicit InlinedStringField(Arena* arena);
+ ~InlinedStringField() { Destruct(); }
+
+ // Lvalue Set. To save space, we pack the donating states of multiple
+ // InlinedStringFields into an uint32_t `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(ConstStringParam value, Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask, MessageLite* msg);
+
+ // Rvalue Set. If this field is donated, this method will undonate this field
+ // by mutating the `donating_states` according to `mask`.
+ void Set(std::string&& value, Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask, MessageLite* msg);
+
+ void Set(const char* str, ::google::protobuf::Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask, MessageLite* msg);
+
+ void Set(const char* str, size_t size, ::google::protobuf::Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask, MessageLite* msg);
+
+ template <typename RefWrappedType>
+ void Set(std::reference_wrapper<RefWrappedType> const_string_ref,
+ ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg);
+
+ void SetBytes(ConstStringParam value, Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask, MessageLite* msg);
+
+ void SetBytes(std::string&& value, Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask, MessageLite* msg);
+
+ void SetBytes(const char* str, ::google::protobuf::Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask, MessageLite* msg);
+
+ void SetBytes(const void* p, size_t size, ::google::protobuf::Arena* arena,
+ bool donated, uint32_t* donating_states, uint32_t mask,
+ MessageLite* msg);
+
+ template <typename RefWrappedType>
+ void SetBytes(std::reference_wrapper<RefWrappedType> const_string_ref,
+ ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg);
+
+ PROTOBUF_NDEBUG_INLINE void SetNoArena(StringPiece value);
+ PROTOBUF_NDEBUG_INLINE void SetNoArena(std::string&& value);
+
+ // Basic accessors.
+ PROTOBUF_NDEBUG_INLINE const std::string& Get() const { return GetNoArena(); }
+ PROTOBUF_NDEBUG_INLINE const std::string& GetNoArena() const;
+
+ // Mutable returns a std::string* 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.
+ std::string* Mutable(Arena* arena, bool donated, uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg);
+ std::string* Mutable(const LazyString& default_value, Arena* arena,
+ bool donated, uint32_t* donating_states, uint32_t mask,
+ MessageLite* msg);
+
+ // Mutable(nullptr_t) is an overload to explicitly support Mutable(nullptr)
+ // calls used by the internal parser logic. This provides API equivalence with
+ // ArenaStringPtr, while still protecting against calls with arena pointers.
+ std::string* Mutable(std::nullptr_t);
+ std::string* MutableNoCopy(std::nullptr_t);
+
+ // Takes a std::string that is heap-allocated, and takes ownership. The
+ // std::string'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 std::string* default_value, std::string* value,
+ Arena* arena, bool donated, uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg);
+
+ void SetAllocatedNoArena(const std::string* default_value,
+ std::string* value);
+
+ // Release returns a std::string* 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 std::string* Release(Arena* arena, bool donated);
+ PROTOBUF_NODISCARD std::string* Release();
+
+ // --------------------------------------------------------
+ // Below functions will be removed in subsequent code change
+ // --------------------------------------------------------
+#ifdef DEPRECATED_METHODS_TO_BE_DELETED
+ PROTOBUF_NODISCARD std::string* Release(const std::string*, Arena* arena,
+ bool donated) {
+ return Release(arena, donated);
+ }
+
+ PROTOBUF_NODISCARD std::string* ReleaseNonDefault(const std::string*,
+ Arena* arena) {
+ return Release();
+ }
+
+ std::string* ReleaseNonDefaultNoArena(const std::string* default_value) {
+ return Release();
+ }
+
+ void Set(const std::string*, ConstStringParam value, Arena* arena,
+ bool donated, uint32_t* donating_states, uint32_t mask,
+ MessageLite* msg) {
+ Set(value, arena, donated, donating_states, mask, msg);
+ }
+
+ void Set(const std::string*, std::string&& value, Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask, MessageLite* msg) {
+ Set(std::move(value), arena, donated, donating_states, mask, msg);
+ }
+
+
+ template <typename FirstParam>
+ void Set(FirstParam, const char* str, ::google::protobuf::Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask, MessageLite* msg) {
+ Set(str, arena, donated, donating_states, mask, msg);
+ }
+
+ template <typename FirstParam>
+ void Set(FirstParam p1, const char* str, size_t size, ::google::protobuf::Arena* arena,
+ bool donated, uint32_t* donating_states, uint32_t mask,
+ MessageLite* msg) {
+ Set(str, size, arena, donated, donating_states, mask, msg);
+ }
+
+ template <typename FirstParam, typename RefWrappedType>
+ void Set(FirstParam p1,
+ std::reference_wrapper<RefWrappedType> const_string_ref,
+ ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ Set(const_string_ref, arena, donated, donating_states, mask, msg);
+ }
+
+ void SetBytes(const std::string*, ConstStringParam value, Arena* arena,
+ bool donated, uint32_t* donating_states, uint32_t mask,
+ MessageLite* msg) {
+ Set(value, arena, donated, donating_states, mask, msg);
+ }
+
+
+ void SetBytes(const std::string*, std::string&& value, Arena* arena,
+ bool donated, uint32_t* donating_states, uint32_t mask,
+ MessageLite* msg) {
+ Set(std::move(value), arena, donated, donating_states, mask, msg);
+ }
+
+ template <typename FirstParam>
+ void SetBytes(FirstParam p1, const char* str, ::google::protobuf::Arena* arena,
+ bool donated, uint32_t* donating_states, uint32_t mask,
+ MessageLite* msg) {
+ SetBytes(str, arena, donated, donating_states, mask, msg);
+ }
+
+ template <typename FirstParam>
+ void SetBytes(FirstParam p1, const void* p, size_t size,
+ ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ SetBytes(p, size, arena, donated, donating_states, mask, msg);
+ }
+
+ template <typename FirstParam, typename RefWrappedType>
+ void SetBytes(FirstParam p1,
+ std::reference_wrapper<RefWrappedType> const_string_ref,
+ ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ SetBytes(const_string_ref.get(), arena, donated, donating_states, mask,
+ msg);
+ }
+
+ void SetNoArena(const std::string*, StringPiece value) {
+ SetNoArena(value);
+ }
+ void SetNoArena(const std::string*, std::string&& value) {
+ SetNoArena(std::move(value));
+ }
+
+ std::string* Mutable(ArenaStringPtr::EmptyDefault, Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask,
+ MessageLite* msg) {
+ return Mutable(arena, donated, donating_states, mask, msg);
+ }
+
+ PROTOBUF_NDEBUG_INLINE std::string* MutableNoArenaNoDefault(
+ const std::string* /*default_value*/) {
+ return MutableNoCopy(nullptr);
+ }
+
+#endif // DEPRECATED_METHODS_TO_BE_DELETED
+
+ // 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(
+ InlinedStringField* lhs, Arena* lhs_arena, bool lhs_arena_dtor_registered,
+ MessageLite* lhs_msg, //
+ InlinedStringField* rhs, Arena* rhs_arena, bool rhs_arena_dtor_registered,
+ MessageLite* rhs_msg);
+
+ // Frees storage (if not on an arena).
+ PROTOBUF_NDEBUG_INLINE void Destroy(const std::string* default_value,
+ Arena* arena) {
+ if (arena == nullptr) {
+ DestroyNoArena(default_value);
+ }
+ }
+ PROTOBUF_NDEBUG_INLINE void DestroyNoArena(const std::string* default_value);
+
+ // Clears content, but keeps allocated std::string, to avoid the overhead of
+ // heap operations. After this returns, the content (as seen by the user) will
+ // always be the empty std::string.
+ PROTOBUF_NDEBUG_INLINE void ClearToEmpty() { ClearNonDefaultToEmpty(); }
+ PROTOBUF_NDEBUG_INLINE void ClearNonDefaultToEmpty() {
+ get_mutable()->clear();
+ }
+
+ // Clears content, but keeps allocated std::string 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);
+
+ // Generated code / reflection only! Returns a mutable pointer to the string.
+ PROTOBUF_NDEBUG_INLINE std::string* UnsafeMutablePointer();
+
+ // InlinedStringField doesn't have things like the `default_value` pointer in
+ // ArenaStringPtr.
+ static constexpr bool IsDefault() { return false; }
+ static constexpr bool IsDefault(const std::string*) { return false; }
+
+ private:
+ void Destruct() { get_mutable()->~basic_string(); }
+
+ PROTOBUF_NDEBUG_INLINE std::string* get_mutable();
+ PROTOBUF_NDEBUG_INLINE const std::string* get_const() const;
+
+ alignas(std::string) char value_[sizeof(std::string)];
+
+ std::string* MutableSlow(::google::protobuf::Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask,
+ MessageLite* msg);
+
+
+ // When constructed in an Arena, we want our destructor to be skipped.
+ friend class ::google::protobuf::Arena;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+};
+
+inline std::string* InlinedStringField::get_mutable() {
+ return reinterpret_cast<std::string*>(&value_);
+}
+
+inline const std::string* InlinedStringField::get_const() const {
+ return reinterpret_cast<const std::string*>(&value_);
+}
+
+inline InlinedStringField::InlinedStringField(
+ const std::string& default_value) {
+ new (get_mutable()) std::string(default_value);
+}
+
+
+inline InlinedStringField::InlinedStringField(Arena* /*arena*/) { Init(); }
+
+inline const std::string& InlinedStringField::GetNoArena() const {
+ return *get_const();
+}
+
+inline void InlinedStringField::SetAllocatedNoArena(
+ const std::string* /*default_value*/, std::string* 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 std::string*) {
+ // This is invoked from the generated message's ArenaDtor, which is used to
+ // clean up objects not allocated on the Arena.
+ this->~InlinedStringField();
+}
+
+inline void InlinedStringField::SetNoArena(StringPiece value) {
+ get_mutable()->assign(value.data(), value.length());
+}
+
+inline void InlinedStringField::SetNoArena(std::string&& value) {
+ get_mutable()->assign(std::move(value));
+}
+
+// Caller should make sure rhs_arena allocated rhs, and lhs_arena allocated lhs.
+inline PROTOBUF_NDEBUG_INLINE void InlinedStringField::InternalSwap(
+ InlinedStringField* lhs, Arena* lhs_arena, bool lhs_arena_dtor_registered,
+ MessageLite* lhs_msg, //
+ InlinedStringField* rhs, Arena* rhs_arena, bool rhs_arena_dtor_registered,
+ MessageLite* rhs_msg) {
+#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
+ lhs->get_mutable()->swap(*rhs->get_mutable());
+ if (!lhs_arena_dtor_registered && rhs_arena_dtor_registered) {
+ lhs_msg->OnDemandRegisterArenaDtor(lhs_arena);
+ } else if (lhs_arena_dtor_registered && !rhs_arena_dtor_registered) {
+ rhs_msg->OnDemandRegisterArenaDtor(rhs_arena);
+ }
+#else
+ (void)lhs_arena;
+ (void)rhs_arena;
+ (void)lhs_arena_dtor_registered;
+ (void)rhs_arena_dtor_registered;
+ (void)lhs_msg;
+ (void)rhs_msg;
+ lhs->get_mutable()->swap(*rhs->get_mutable());
+#endif
+}
+
+inline void InlinedStringField::Set(ConstStringParam value, Arena* arena,
+ bool donated, uint32_t* /*donating_states*/,
+ uint32_t /*mask*/, MessageLite* /*msg*/) {
+ (void)arena;
+ (void)donated;
+ SetNoArena(value);
+}
+
+inline void InlinedStringField::Set(const char* str, ::google::protobuf::Arena* arena,
+ bool donated, uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ Set(ConstStringParam(str), arena, donated, donating_states, mask, msg);
+}
+
+inline void InlinedStringField::Set(const char* str, size_t size,
+ ::google::protobuf::Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask,
+ MessageLite* msg) {
+ Set(ConstStringParam{str, size}, arena, donated, donating_states, mask, msg);
+}
+
+inline void InlinedStringField::SetBytes(ConstStringParam value, Arena* arena,
+ bool donated,
+ uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ Set(value, arena, donated, donating_states, mask, msg);
+}
+
+inline void InlinedStringField::SetBytes(std::string&& value, Arena* arena,
+ bool donated,
+ uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ Set(std::move(value), arena, donated, donating_states, mask, msg);
+}
+
+inline void InlinedStringField::SetBytes(const char* str,
+ ::google::protobuf::Arena* arena, bool donated,
+ uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ Set(str, arena, donated, donating_states, mask, msg);
+}
+
+inline void InlinedStringField::SetBytes(const void* p, size_t size,
+ ::google::protobuf::Arena* arena, bool donated,
+ uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ Set(static_cast<const char*>(p), size, arena, donated, donating_states, mask,
+ msg);
+}
+
+template <typename RefWrappedType>
+inline void InlinedStringField::Set(
+ std::reference_wrapper<RefWrappedType> const_string_ref,
+ ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ Set(const_string_ref.get(), arena, donated, donating_states, mask, msg);
+}
+
+template <typename RefWrappedType>
+inline void InlinedStringField::SetBytes(
+ std::reference_wrapper<RefWrappedType> const_string_ref,
+ ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
+ uint32_t mask, MessageLite* msg) {
+ Set(const_string_ref.get(), arena, donated, donating_states, mask, msg);
+}
+
+inline std::string* InlinedStringField::UnsafeMutablePointer() {
+ return get_mutable();
+}
+
+inline std::string* InlinedStringField::Mutable(std::nullptr_t) {
+ return get_mutable();
+}
+
+inline std::string* InlinedStringField::MutableNoCopy(std::nullptr_t) {
+ 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/toolkit/components/protobuf/src/google/protobuf/io/coded_stream.cc b/toolkit/components/protobuf/src/google/protobuf/io/coded_stream.cc
new file mode 100644
index 0000000000..487e1b8a37
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/coded_stream.cc
@@ -0,0 +1,967 @@
+// 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>
+
+
+// Must be included last.
+#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() {
+ uint32_t 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/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(std::string* 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(std::string* 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(uint32_t* value) {
+ uint8_t bytes[sizeof(*value)];
+
+ const uint8_t* ptr;
+ if (BufferSize() >= static_cast<int64_t>(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(uint64_t* value) {
+ uint8_t bytes[sizeof(*value)];
+
+ const uint8_t* ptr;
+ if (BufferSize() >= static_cast<int64_t>(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, uint64_t* value) {
+ GOOGLE_DCHECK_GT(N, 0);
+ uint64_t result = static_cast<uint64_t>(buffer[N - 1]) << (7 * (N - 1));
+ for (size_t i = 0, offset = 0; i < N - 1; i++, offset += 7) {
+ result += static_cast<uint64_t>(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(uint32_t first_byte,
+ const uint8_t* buffer,
+ uint32_t* value);
+inline ::std::pair<bool, const uint8_t*> ReadVarint32FromArray(
+ uint32_t first_byte, const uint8_t* buffer, uint32_t* 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;
+ uint32_t b;
+ uint32_t 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 irrelevant.
+
+ // 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, uint64_t* value);
+inline ::std::pair<bool, const uint8_t*> ReadVarint64FromArray(
+ const uint8_t* buffer, uint64_t* 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(uint32_t* value) {
+ // Directly invoke ReadVarint64Fallback, since we already tried to optimize
+ // for one-byte varints.
+ std::pair<uint64_t, bool> p = ReadVarint64Fallback();
+ *value = static_cast<uint32_t>(p.first);
+ return p.second;
+}
+
+int64_t CodedInputStream::ReadVarint32Fallback(uint32_t 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";
+ uint32_t 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%
+ uint32_t temp;
+ return ReadVarint32Slow(&temp) ? static_cast<int64_t>(temp) : -1;
+ }
+}
+
+int CodedInputStream::ReadVarintSizeAsIntSlow() {
+ // Directly invoke ReadVarint64Fallback, since we already tried to optimize
+ // for one-byte varints.
+ std::pair<uint64_t, bool> p = ReadVarint64Fallback();
+ if (!p.second || p.first > static_cast<uint64_t>(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))) {
+ uint64_t temp;
+ ::std::pair<bool, const uint8_t*> p = ReadVarint64FromArray(buffer_, &temp);
+ if (!p.first || temp > static_cast<uint64_t>(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();
+ }
+}
+
+uint32_t 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.
+ uint64_t result = 0;
+ if (!ReadVarint64(&result)) return 0;
+ return static_cast<uint32_t>(result);
+}
+
+uint32_t CodedInputStream::ReadTagFallback(uint32_t 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;
+ }
+ uint32_t 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(uint64_t* 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.
+
+ uint64_t result = 0;
+ int count = 0;
+ uint32_t b;
+
+ do {
+ if (count == kMaxVarintBytes) {
+ *value = 0;
+ return false;
+ }
+ while (buffer_ == buffer_end_) {
+ if (!Refresh()) {
+ *value = 0;
+ return false;
+ }
+ }
+ b = *buffer_;
+ result |= static_cast<uint64_t>(b & 0x7F) << (7 * count);
+ Advance(1);
+ ++count;
+ } while (b & 0x80);
+
+ *value = result;
+ return true;
+}
+
+std::pair<uint64_t, 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))) {
+ uint64_t 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 {
+ uint64_t 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);
+ 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);
+ uint32_t 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);
+ uint32_t 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);
+ uint64_t 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);
+ uint64_t buffer;
+ std::memcpy(&buffer, p, 8);
+ p += 8;
+ ptr = CodedOutputStream::WriteLittleEndian64ToArray(buffer, ptr);
+ }
+ return ptr;
+}
+#endif
+
+
+uint8_t* EpsCopyOutputStream::WriteStringMaybeAliasedOutline(uint32_t num,
+ const std::string& s,
+ uint8_t* ptr) {
+ ptr = EnsureSpace(ptr);
+ uint32_t size = s.size();
+ ptr = WriteLengthDelim(num, size, ptr);
+ return WriteRawMaybeAliased(s.data(), size, ptr);
+}
+
+uint8_t* EpsCopyOutputStream::WriteStringOutline(uint32_t num, const std::string& s,
+ uint8_t* ptr) {
+ ptr = EnsureSpace(ptr);
+ uint32_t size = s.size();
+ ptr = WriteLengthDelim(num, size, ptr);
+ return WriteRaw(s.data(), size, ptr);
+}
+
+std::atomic<bool> CodedOutputStream::default_serialization_deterministic_{
+ false};
+
+CodedOutputStream::~CodedOutputStream() { Trim(); }
+
+
+uint8_t* CodedOutputStream::WriteStringWithSizeToArray(const std::string& str,
+ uint8_t* target) {
+ GOOGLE_DCHECK_LE(str.size(), std::numeric_limits<uint32_t>::max());
+ target = WriteVarint32ToArray(str.size(), target);
+ return WriteStringToArray(str, target);
+}
+
+uint8_t* CodedOutputStream::WriteVarint32ToArrayOutOfLineHelper(uint32_t 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/toolkit/components/protobuf/src/google/protobuf/io/coded_stream.h b/toolkit/components/protobuf/src/google/protobuf/io/coded_stream.h
new file mode 100644
index 0000000000..c8fc994f91
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/coded_stream.h
@@ -0,0 +1,1799 @@
+// 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;
+// }
+//
+// uint32_t 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>
+
+#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
+
+
+#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>
+
+
+// Must be included last.
+#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(std::string* buffer, int size);
+
+
+ // Read a 32-bit little-endian integer.
+ bool ReadLittleEndian32(uint32_t* value);
+ // Read a 64-bit little-endian integer.
+ bool ReadLittleEndian64(uint64_t* 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,
+ uint32_t* value);
+ // Read a 64-bit little-endian integer.
+ static const uint8_t* ReadLittleEndian64FromArray(const uint8_t* buffer,
+ uint64_t* 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 uint32_t, but may be more efficient.
+ bool ReadVarint32(uint32_t* value);
+ // Read an unsigned integer with Varint encoding.
+ bool ReadVarint64(uint64_t* 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 uint32_t ReadTag() {
+ return last_tag_ = ReadTagNoLastTag();
+ }
+
+ PROTOBUF_ALWAYS_INLINE uint32_t 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<uint32_t, bool> ReadTagWithCutoff(uint32_t cutoff) {
+ std::pair<uint32_t, bool> result = ReadTagWithCutoffNoLastTag(cutoff);
+ last_tag_ = result.first;
+ return result;
+ }
+
+ PROTOBUF_ALWAYS_INLINE
+ std::pair<uint32_t, bool> ReadTagWithCutoffNoLastTag(uint32_t 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(uint32_t 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,
+ uint32_t 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(uint32_t expected);
+ void SetLastTag(uint32_t 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.
+ uint32_t 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 uint32_t it read otherwise. The latter has a bool
+ // indicating success or failure as part of its return type.
+ int64_t ReadVarint32Fallback(uint32_t first_byte_or_zero);
+ int ReadVarintSizeAsIntFallback();
+ std::pair<uint64_t, bool> ReadVarint64Fallback();
+ bool ReadVarint32Slow(uint32_t* value);
+ bool ReadVarint64Slow(uint64_t* value);
+ int ReadVarintSizeAsIntSlow();
+ bool ReadLittleEndian32Fallback(uint32_t* value);
+ bool ReadLittleEndian64Fallback(uint64_t* 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.
+ uint32_t ReadTagFallback(uint32_t first_byte_or_zero);
+ uint32_t ReadTagSlow();
+ bool ReadStringFallback(std::string* 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(uint32_t num, const std::string& 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(uint32_t num, const std::string& s,
+ uint8_t* ptr) {
+ return WriteStringMaybeAliased(num, s, ptr);
+ }
+
+ template <typename T>
+ PROTOBUF_ALWAYS_INLINE uint8_t* WriteString(uint32_t 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(uint32_t 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_;
+ bool skip_check_consistency = false;
+
+ 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(uint32_t 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(uint32_t num, uint32_t wt,
+ uint8_t* ptr) {
+ GOOGLE_DCHECK(ptr < end_); // NOLINT
+ return UnsafeVarint((num << 3) | wt, ptr);
+ }
+
+ PROTOBUF_ALWAYS_INLINE uint8_t* WriteLengthDelim(int num, uint32_t 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(uint32_t num, const std::string& s,
+ uint8_t* ptr);
+ uint8_t* WriteStringOutline(uint32_t num, const std::string& 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 uint32_t Encode32(uint32_t v) { return v; }
+ static uint64_t Encode64(uint64_t v) { return v; }
+ static uint32_t ZigZagEncode32(int32_t v) {
+ return (static_cast<uint32_t>(v) << 1) ^ static_cast<uint32_t>(v >> 31);
+ }
+ static uint64_t ZigZagEncode64(int64_t v) {
+ return (static_cast<uint64_t>(v) << 1) ^ static_cast<uint64_t>(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(uint32_t 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);
+#if !defined(PROTOBUF_LITTLE_ENDIAN) || \
+ defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+ 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) {
+#if defined(PROTOBUF_LITTLE_ENDIAN) && \
+ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+ 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) {
+#if defined(PROTOBUF_LITTLE_ENDIAN) && \
+ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+ 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:
+ // Creates a CodedOutputStream that writes to the given `stream`.
+ // The provided stream must publicly derive from `ZeroCopyOutputStream`.
+ template <class Stream, class = typename std::enable_if<std::is_base_of<
+ ZeroCopyOutputStream, Stream>::value>::type>
+ explicit CodedOutputStream(Stream* stream);
+
+ // Creates a CodedOutputStream that writes to the given `stream`, and does
+ // an 'eager initialization' of the internal state if `eager_init` is true.
+ // The provided stream must publicly derive from `ZeroCopyOutputStream`.
+ template <class Stream, class = typename std::enable_if<std::is_base_of<
+ ZeroCopyOutputStream, Stream>::value>::type>
+ CodedOutputStream(Stream* stream, bool eager_init);
+
+ // 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 std::string& str);
+ // Like WriteString() but writing directly to the target array.
+ static uint8_t* WriteStringToArray(const std::string& str, uint8_t* target);
+ // Write the varint-encoded size of str followed by str.
+ static uint8_t* WriteStringWithSizeToArray(const std::string& str,
+ uint8_t* target);
+
+
+ // Write a 32-bit little-endian integer.
+ void WriteLittleEndian32(uint32_t value) {
+ cur_ = impl_.EnsureSpace(cur_);
+ SetCur(WriteLittleEndian32ToArray(value, Cur()));
+ }
+ // Like WriteLittleEndian32() but writing directly to the target array.
+ static uint8_t* WriteLittleEndian32ToArray(uint32_t value, uint8_t* target);
+ // Write a 64-bit little-endian integer.
+ void WriteLittleEndian64(uint64_t value) {
+ cur_ = impl_.EnsureSpace(cur_);
+ SetCur(WriteLittleEndian64ToArray(value, Cur()));
+ }
+ // Like WriteLittleEndian64() but writing directly to the target array.
+ static uint8_t* WriteLittleEndian64ToArray(uint64_t value, uint8_t* target);
+
+ // Write an unsigned integer with Varint encoding. Writing a 32-bit value
+ // is equivalent to casting it to uint64_t and writing it as a 64-bit value,
+ // but may be more efficient.
+ void WriteVarint32(uint32_t value);
+ // Like WriteVarint32() but writing directly to the target array.
+ static uint8_t* WriteVarint32ToArray(uint32_t 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(uint32_t value,
+ uint8_t* target);
+ // Write an unsigned integer with Varint encoding.
+ void WriteVarint64(uint64_t value);
+ // Like WriteVarint64() but writing directly to the target array.
+ static uint8_t* WriteVarint64ToArray(uint64_t 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(int32_t value);
+ // Like WriteVarint32SignExtended() but writing directly to the target array.
+ static uint8_t* WriteVarint32SignExtendedToArray(int32_t 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(uint32_t value);
+ // Like WriteTag() but writing directly to the target array.
+ PROTOBUF_ALWAYS_INLINE
+ static uint8_t* WriteTagToArray(uint32_t value, uint8_t* target);
+
+ // Returns the number of bytes needed to encode the given value as a varint.
+ static size_t VarintSize32(uint32_t value);
+ // Returns the number of bytes needed to encode the given value as a varint.
+ static size_t VarintSize64(uint64_t value);
+
+ // If negative, 10 bytes. Otherwise, same as VarintSize32().
+ static size_t VarintSize32SignExtended(int32_t value);
+
+ // Same as above, plus one. The additional one comes at no compute cost.
+ static size_t VarintSize32PlusOne(uint32_t value);
+ static size_t VarintSize64PlusOne(uint64_t value);
+ static size_t VarintSize32SignExtendedPlusOne(int32_t value);
+
+ // Compile-time equivalent of VarintSize32().
+ template <uint32_t 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 deterministic
+ // 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:
+ template <class Stream>
+ void InitEagerly(Stream* stream);
+
+ EpsCopyOutputStream impl_;
+ uint8_t* cur_;
+ int64_t 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(uint32_t 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(uint32_t* value) {
+ uint32_t v = 0;
+ if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) {
+ v = *buffer_;
+ if (v < 0x80) {
+ *value = v;
+ Advance(1);
+ return true;
+ }
+ }
+ int64_t result = ReadVarint32Fallback(v);
+ *value = static_cast<uint32_t>(result);
+ return result >= 0;
+}
+
+inline bool CodedInputStream::ReadVarint64(uint64_t* value) {
+ if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) {
+ *value = *buffer_;
+ Advance(1);
+ return true;
+ }
+ std::pair<uint64_t, 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, uint32_t* value) {
+#if defined(PROTOBUF_LITTLE_ENDIAN) && \
+ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+ memcpy(value, buffer, sizeof(*value));
+ return buffer + sizeof(*value);
+#else
+ *value = (static_cast<uint32_t>(buffer[0])) |
+ (static_cast<uint32_t>(buffer[1]) << 8) |
+ (static_cast<uint32_t>(buffer[2]) << 16) |
+ (static_cast<uint32_t>(buffer[3]) << 24);
+ return buffer + sizeof(*value);
+#endif
+}
+// static
+inline const uint8_t* CodedInputStream::ReadLittleEndian64FromArray(
+ const uint8_t* buffer, uint64_t* value) {
+#if defined(PROTOBUF_LITTLE_ENDIAN) && \
+ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+ memcpy(value, buffer, sizeof(*value));
+ return buffer + sizeof(*value);
+#else
+ uint32_t part0 = (static_cast<uint32_t>(buffer[0])) |
+ (static_cast<uint32_t>(buffer[1]) << 8) |
+ (static_cast<uint32_t>(buffer[2]) << 16) |
+ (static_cast<uint32_t>(buffer[3]) << 24);
+ uint32_t part1 = (static_cast<uint32_t>(buffer[4])) |
+ (static_cast<uint32_t>(buffer[5]) << 8) |
+ (static_cast<uint32_t>(buffer[6]) << 16) |
+ (static_cast<uint32_t>(buffer[7]) << 24);
+ *value = static_cast<uint64_t>(part0) | (static_cast<uint64_t>(part1) << 32);
+ return buffer + sizeof(*value);
+#endif
+}
+
+inline bool CodedInputStream::ReadLittleEndian32(uint32_t* value) {
+#if defined(PROTOBUF_LITTLE_ENDIAN) && \
+ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+ 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(uint64_t* value) {
+#if defined(PROTOBUF_LITTLE_ENDIAN) && \
+ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+ 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 uint32_t CodedInputStream::ReadTagNoLastTag() {
+ uint32_t 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<uint32_t, bool> CodedInputStream::ReadTagWithCutoffNoLastTag(
+ uint32_t 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.
+ uint32_t 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 uint32_t kMax1ByteVarint = 0x7f;
+ uint32_t 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 uint32_t kMax2ByteVarint = (0x7f << 7) + 0x7f;
+ uint32_t 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 uint32_t tag = ReadTagFallback(first_byte_or_zero);
+ return std::make_pair(tag, static_cast<uint32_t>(tag - 1) < cutoff);
+}
+
+inline bool CodedInputStream::LastTagWas(uint32_t expected) {
+ return last_tag_ == expected;
+}
+
+inline bool CodedInputStream::ConsumedEntireMessage() {
+ return legitimate_message_end_;
+}
+
+inline bool CodedInputStream::ExpectTag(uint32_t 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, uint32_t 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<int32_t>::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);
+}
+
+template <class Stream, class>
+inline CodedOutputStream::CodedOutputStream(Stream* stream)
+ : impl_(stream, IsDefaultSerializationDeterministic(), &cur_),
+ start_count_(stream->ByteCount()) {
+ InitEagerly(stream);
+}
+
+template <class Stream, class>
+inline CodedOutputStream::CodedOutputStream(Stream* stream, bool eager_init)
+ : impl_(stream, IsDefaultSerializationDeterministic(), &cur_),
+ start_count_(stream->ByteCount()) {
+ if (eager_init) {
+ InitEagerly(stream);
+ }
+}
+
+template <class Stream>
+inline void CodedOutputStream::InitEagerly(Stream* stream) {
+ void* data;
+ int size;
+ if (PROTOBUF_PREDICT_TRUE(stream->Next(&data, &size) && size > 0)) {
+ cur_ = impl_.SetInitialBuffer(data, size);
+ }
+}
+
+inline uint8_t* CodedOutputStream::WriteVarint32ToArray(uint32_t value,
+ uint8_t* target) {
+ return EpsCopyOutputStream::UnsafeVarint(value, target);
+}
+
+inline uint8_t* CodedOutputStream::WriteVarint32ToArrayOutOfLine(
+ uint32_t 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(uint64_t value,
+ uint8_t* target) {
+ return EpsCopyOutputStream::UnsafeVarint(value, target);
+}
+
+inline void CodedOutputStream::WriteVarint32SignExtended(int32_t value) {
+ WriteVarint64(static_cast<uint64_t>(value));
+}
+
+inline uint8_t* CodedOutputStream::WriteVarint32SignExtendedToArray(
+ int32_t value, uint8_t* target) {
+ return WriteVarint64ToArray(static_cast<uint64_t>(value), target);
+}
+
+inline uint8_t* CodedOutputStream::WriteLittleEndian32ToArray(uint32_t value,
+ uint8_t* target) {
+#if defined(PROTOBUF_LITTLE_ENDIAN) && \
+ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+ 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(uint64_t value,
+ uint8_t* target) {
+#if defined(PROTOBUF_LITTLE_ENDIAN) && \
+ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+ memcpy(target, &value, sizeof(value));
+#else
+ uint32_t part0 = static_cast<uint32_t>(value);
+ uint32_t part1 = static_cast<uint32_t>(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(uint32_t value) {
+ cur_ = impl_.EnsureSpace(cur_);
+ SetCur(WriteVarint32ToArray(value, Cur()));
+}
+
+inline void CodedOutputStream::WriteVarint64(uint64_t value) {
+ cur_ = impl_.EnsureSpace(cur_);
+ SetCur(WriteVarint64ToArray(value, Cur()));
+}
+
+inline void CodedOutputStream::WriteTag(uint32_t value) {
+ WriteVarint32(value);
+}
+
+inline uint8_t* CodedOutputStream::WriteTagToArray(uint32_t value,
+ uint8_t* target) {
+ return WriteVarint32ToArray(value, target);
+}
+
+inline size_t CodedOutputStream::VarintSize32(uint32_t 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.
+ uint32_t log2value = Bits::Log2FloorNonZero(value | 0x1);
+ return static_cast<size_t>((log2value * 9 + 73) / 64);
+}
+
+inline size_t CodedOutputStream::VarintSize32PlusOne(uint32_t value) {
+ // Same as above, but one more.
+ uint32_t log2value = Bits::Log2FloorNonZero(value | 0x1);
+ return static_cast<size_t>((log2value * 9 + 73 + 64) / 64);
+}
+
+inline size_t CodedOutputStream::VarintSize64(uint64_t 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.
+ uint32_t log2value = Bits::Log2FloorNonZero64(value | 0x1);
+ return static_cast<size_t>((log2value * 9 + 73) / 64);
+}
+
+inline size_t CodedOutputStream::VarintSize64PlusOne(uint64_t value) {
+ // Same as above, but one more.
+ uint32_t log2value = Bits::Log2FloorNonZero64(value | 0x1);
+ return static_cast<size_t>((log2value * 9 + 73 + 64) / 64);
+}
+
+inline size_t CodedOutputStream::VarintSize32SignExtended(int32_t value) {
+ return VarintSize64(static_cast<uint64_t>(int64_t{value}));
+}
+
+inline size_t CodedOutputStream::VarintSize32SignExtendedPlusOne(
+ int32_t value) {
+ return VarintSize64PlusOne(static_cast<uint64_t>(int64_t{value}));
+}
+
+inline void CodedOutputStream::WriteString(const std::string& 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 std::string& 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/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.cc b/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.cc
new file mode 100644
index 0000000000..a5284b3e12
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.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: 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/port.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() {
+ internal::SizedDelete(output_buffer_, output_buffer_length_);
+ 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 {
+ int64_t 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();
+ internal::SizedDelete(input_buffer_, input_buffer_length_);
+}
+
+// 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/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.h b/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.h
new file mode 100644
index 0000000000..4cf71b6c32
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.h
@@ -0,0 +1,205 @@
+// 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"
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// A ZeroCopyInputStream that reads compressed data through zlib
+class PROTOBUF_EXPORT GzipInputStream PROTOBUF_FUTURE_FINAL
+ : 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_;
+ int64_t byte_count_;
+
+ int Inflate(int flush);
+ void DoNextOutput(const void** data, int* size);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream);
+};
+
+class PROTOBUF_EXPORT GzipOutputStream PROTOBUF_FUTURE_FINAL
+ : 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/toolkit/components/protobuf/src/google/protobuf/io/io_win32.cc b/toolkit/components/protobuf/src/google/protobuf/io/io_win32.cc
new file mode 100644
index 0000000000..4e81908809
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/io_win32.cc
@@ -0,0 +1,471 @@
+// 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 std::string;
+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)) {
+ matched = ExpandWildcardsResult::kErrorOutputPathConversion;
+ break;
+ }
+
+ 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/toolkit/components/protobuf/src/google/protobuf/io/io_win32.h b/toolkit/components/protobuf/src/google/protobuf/io/io_win32.h
new file mode 100644
index 0000000000..a72b4ea3cf
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/io_win32.h
@@ -0,0 +1,141 @@
+// 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/port.h>
+
+// Must be included last.
+#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 std::string& path, std::function<void(const std::string&)> 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, std::string* 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, std::string* 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/toolkit/components/protobuf/src/google/protobuf/io/package_info.h b/toolkit/components/protobuf/src/google/protobuf/io/package_info.h
new file mode 100644
index 0000000000..46c3dac917
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/package_info.h
@@ -0,0 +1,53 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file exists solely to document the google::protobuf::io namespace.
+// It is not compiled into anything, but it may be read by an automated
+// documentation generator.
+
+namespace google {
+namespace protobuf {
+
+// Auxiliary classes used for I/O.
+//
+// The Protocol Buffer library uses the classes in this package to deal with
+// I/O and encoding/decoding raw bytes. Most users will not need to
+// deal with this package. However, users who want to adapt the system to
+// work with their own I/O abstractions -- e.g., to allow Protocol Buffers
+// to be read from a different kind of input stream without the need for a
+// temporary buffer -- should take a closer look.
+namespace io {}
+
+} // namespace protobuf
+} // namespace google
diff --git a/toolkit/components/protobuf/src/google/protobuf/io/printer.cc b/toolkit/components/protobuf/src/google/protobuf/io/printer.cc
new file mode 100644
index 0000000000..47bd00b50a
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/printer.cc
@@ -0,0 +1,403 @@
+// 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 invoked Next() at least once, and we have never failed.
+ // Note that we always call `Backup`, i.e. we call BackUp(0) as some output
+ // streams have buffered output, and BackUp() serves as a flush event in such
+ // implementations.
+ if (buffer_ != nullptr && !failed_) {
+ output_->BackUp(buffer_size_);
+ }
+}
+
+bool Printer::GetSubstitutionRange(const char* varname,
+ std::pair<size_t, size_t>* range) {
+ std::map<std::string, 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 std::string& 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<std::string, std::string>& 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;
+
+ std::string 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<std::string, std::string>::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<std::string, 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 std::string& 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<std::string>::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<std::string>& args,
+ const std::map<std::string, std::string>& 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<std::string>& args,
+ const std::map<std::string, std::string>& 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--;
+ std::string var_name{
+ start_var, static_cast<std::string::size_type>(end_var - start_var)};
+ std::string 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/toolkit/components/protobuf/src/google/protobuf/io/printer.h b/toolkit/components/protobuf/src/google/protobuf/io/printer.h
new file mode 100644
index 0000000000..92a4321c04
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/printer.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.
+
+// 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>
+
+// Must be included last.
+#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>, std::string> 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 std::string& 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 std::string& 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 std::string& 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 std::string& 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<std::string, std::string>& 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<std::string, std::string> 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 std::string& 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<std::string>& args,
+ const std::map<std::string, std::string>& 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 std::string& file_path, const std::vector<int>& path);
+
+ // Base case
+ void PrintInternal(std::map<std::string, std::string>* vars,
+ const char* text) {
+ Print(*vars, text);
+ }
+
+ template <typename... Args>
+ void PrintInternal(std::map<std::string, std::string>* vars, const char* text,
+ const char* key, const std::string& 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<std::string>& args,
+ const std::map<std::string, std::string>& 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_;
+
+ std::string 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<std::string, 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<std::string> 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/toolkit/components/protobuf/src/google/protobuf/io/strtod.cc b/toolkit/components/protobuf/src/google/protobuf/io/strtod.cc
new file mode 100644
index 0000000000..03acb5b294
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/io/strtod.h b/toolkit/components/protobuf/src/google/protobuf/io/strtod.h
new file mode 100644
index 0000000000..38f544af34
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/io/tokenizer.cc b/toolkit/components/protobuf/src/google/protobuf/io/tokenizer.cc
new file mode 100644
index 0000000000..f9e07763e7
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/tokenizer.cc
@@ -0,0 +1,1239 @@
+// 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/strutil.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/io/strtod.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/stl_util.h>
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+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.
+// Represents integer values of digits.
+// Uses 36 to indicate an invalid character since we support
+// bases up to 36.
+static const int8_t kAsciiToInt[256] = {
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // 00-0F
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // 10-1F
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // ' '-'/'
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // '0'-'9'
+ 36, 36, 36, 36, 36, 36, 36, // ':'-'@'
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'P'
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, // 'Q'-'Z'
+ 36, 36, 36, 36, 36, 36, // '['-'`'
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'a'-'p'
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, // 'q'-'z'
+ 36, 36, 36, 36, 36, // '{'-DEL
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // 80-8F
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // 90-9F
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // A0-AF
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // B0-BF
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // C0-CF
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // D0-DF
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // E0-EF
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // F0-FF
+};
+
+inline int DigitValue(char digit) { return kAsciiToInt[digit & 0xFF]; }
+
+// 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(std::string* 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(&current_.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(std::string* content) {
+ if (content != NULL) RecordTo(content);
+
+ while (current_char_ != '\0' && current_char_ != '\n') {
+ NextChar();
+ }
+ TryConsume('\n');
+
+ if (content != NULL) StopRecording();
+}
+
+void Tokenizer::ConsumeBlockComment(std::string* 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.
+ 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(std::string* prev_trailing_comments,
+ std::vector<std::string>* detached_comments,
+ std::string* 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.
+ std::string* 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.
+ std::string* 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:
+ std::string* prev_trailing_comments_;
+ std::vector<std::string>* detached_comments_;
+ std::string* next_leading_comments_;
+
+ std::string 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(std::string* prev_trailing_comments,
+ std::vector<std::string>* detached_comments,
+ std::string* 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 std::string& text, uint64_t max_value,
+ uint64_t* output) {
+ // We can't just use strtoull() because (a) it accepts negative numbers,
+ // (b) We want additional range checks, (c) it reports overflows via errno.
+
+#if 0
+ const char *str_begin = text.c_str();
+ if (*str_begin == '-') return false;
+ char *str_end = nullptr;
+ errno = 0;
+ *output = std::strtoull(str_begin, &str_end, 0);
+ return (errno == 0 && str_end && *str_end == '\0' && *output <= max_value);
+#endif
+
+ const char* ptr = text.c_str();
+ int base = 10;
+ uint64_t overflow_if_mul_base = (kuint64max / 10) + 1;
+ if (ptr[0] == '0') {
+ if (ptr[1] == 'x' || ptr[1] == 'X') {
+ // This is hex.
+ base = 16;
+ overflow_if_mul_base = (kuint64max / 16) + 1;
+ ptr += 2;
+ } else {
+ // This is octal.
+ base = 8;
+ overflow_if_mul_base = (kuint64max / 8) + 1;
+ }
+ }
+
+ uint64_t result = 0;
+ // For all the leading '0's, and also the first non-zero character, we
+ // don't need to multiply.
+ while (*ptr != '\0') {
+ int digit = DigitValue(*ptr++);
+ if (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 (digit != 0) {
+ result = digit;
+ break;
+ }
+ }
+ 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 (result >= overflow_if_mul_base) {
+ // We know the multiply we're about to do will overflow, so exit now.
+ return false;
+ }
+ // We know that result * base won't overflow, but adding digit might...
+ result = result * base + digit;
+ // C++ guarantees defined "wrap" semantics when unsigned integer
+ // operations overflow, making this a fast way to check if adding
+ // digit made result overflow, and thus, wrap around.
+ if (result < static_cast<uint64_t>(base)) return false;
+ }
+ if (result > max_value) return false;
+
+ *output = result;
+ return true;
+}
+
+double Tokenizer::ParseFloat(const std::string& 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(uint32_t code_point, std::string* output) {
+ uint32_t 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, uint32_t* 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 uint32_t kMinHeadSurrogate = 0xd800;
+static const uint32_t kMaxHeadSurrogate = 0xdc00;
+static const uint32_t kMinTrailSurrogate = 0xdc00;
+static const uint32_t kMaxTrailSurrogate = 0xe000;
+
+static inline bool IsHeadSurrogate(uint32_t code_point) {
+ return (code_point >= kMinHeadSurrogate) && (code_point < kMaxHeadSurrogate);
+}
+
+static inline bool IsTrailSurrogate(uint32_t code_point) {
+ return (code_point >= kMinTrailSurrogate) &&
+ (code_point < kMaxTrailSurrogate);
+}
+
+// Combine a head and trail surrogate into a single Unicode code point.
+static uint32_t AssembleUTF16(uint32_t head_surrogate,
+ uint32_t 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, uint32_t* 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') {
+ uint32_t 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 std::string& text,
+ std::string* 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') {
+ uint32_t 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 std::string& s) {
+ for (const char character : s) {
+ if (!CharacterClass::InClass(character)) return false;
+ }
+ return true;
+}
+
+bool Tokenizer::IsIdentifier(const std::string& 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
+
+#include <google/protobuf/port_undef.inc>
diff --git a/toolkit/components/protobuf/src/google/protobuf/io/tokenizer.h b/toolkit/components/protobuf/src/google/protobuf/io/tokenizer.h
new file mode 100644
index 0000000000..4abab7e30c
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/tokenizer.h
@@ -0,0 +1,442 @@
+// 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>
+
+// Must be included last.
+#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 std::string& 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 std::string& /* 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;
+ std::string 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(std::string* prev_trailing_comments,
+ std::vector<std::string>* detached_comments,
+ std::string* 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 std::string& 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 std::string& text, std::string* output);
+
+ // Identical to ParseString, but appends to output.
+ static void ParseStringAppend(const std::string& text, std::string* 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 std::string& text, uint64_t max_value,
+ uint64_t* 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 std::string& 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(&current_.text). record_start_ is the
+ // position within the current buffer where recording started.
+ std::string* 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(std::string* 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 std::string& 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(std::string* content);
+ // Consume until "*/".
+ void ConsumeBlockComment(std::string* 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 std::string& text,
+ std::string* 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/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.cc b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.cc
new file mode 100644
index 0000000000..f81555e554
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.h b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.h
new file mode 100644
index 0000000000..2041cbf648
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.h
@@ -0,0 +1,260 @@
+// 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 <google/protobuf/stubs/common.h>
+
+
+// Must be included last.
+#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.
+ //
+ // This method can be called with `count = 0` to finalize (flush) any
+ // previously returned buffer. For example, a file output stream can
+ // flush buffers returned from a previous call to Next() upon such
+ // BackUp(0) invocations. ZeroCopyOutputStream callers should always
+ // invoke BackUp() after a final Next() call, even if there is no
+ // excess buffer data to be backed up to indicate a flush point.
+ //
+ // 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/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc
new file mode 100644
index 0000000000..c66bc862a7
--- /dev/null
+++ b/toolkit/components/protobuf/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_(&copying_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(&copying_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_(&copying_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_(&copying_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.
+ int64_t 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.
+ int64_t 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/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h
new file mode 100644
index 0000000000..a385992f20
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h
@@ -0,0 +1,336 @@
+// 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>
+
+// Must be included last.
+#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 PROTOBUF_FUTURE_FINAL
+ : 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 PROTOBUF_FUTURE_FINAL
+ : 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 PROTOBUF_FUTURE_FINAL
+ : 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 PROTOBUF_FUTURE_FINAL
+ : 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 PROTOBUF_FUTURE_FINAL
+ : 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 PROTOBUF_FUTURE_FINAL
+ : 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 PROTOBUF_FUTURE_FINAL
+ : 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 PROTOBUF_FUTURE_FINAL
+ : 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 PROTOBUF_FUTURE_FINAL
+ : 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_;
+ int64_t 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/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
new file mode 100644
index 0000000000..b3dfd84c7f
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.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: 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_LE(count, last_returned_size_)
+ << "BackUp() can not exceed the size of the last Next() call.";
+ GOOGLE_CHECK_GE(count, 0);
+ position_ -= count;
+ last_returned_size_ -= count;
+}
+
+int64_t ArrayOutputStream::ByteCount() const { return position_; }
+
+// ===================================================================
+
+StringOutputStream::StringOutputStream(std::string* 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) {
+ if (count == 0) {
+ Flush();
+ return;
+ }
+ 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,
+ int64_t 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/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h
new file mode 100644
index 0000000000..cbda32871e
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h
@@ -0,0 +1,413 @@
+// 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>
+
+
+// Must be included last.
+#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 PROTOBUF_FUTURE_FINAL
+ : 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 PROTOBUF_FUTURE_FINAL
+ : 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 PROTOBUF_FUTURE_FINAL
+ : 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(std::string* 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;
+
+ std::string* 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.
+ int64_t 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.
+ int64_t 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 PROTOBUF_FUTURE_FINAL
+ : public ZeroCopyInputStream {
+ public:
+ LimitingInputStream(ZeroCopyInputStream* input, int64_t 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_;
+ int64_t limit_; // Decreases as we go, becomes negative if we overshoot.
+ int64_t 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(std::string* 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(std::string* 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/toolkit/components/protobuf/src/google/protobuf/map.cc b/toolkit/components/protobuf/src/google/protobuf/map.cc
new file mode 100644
index 0000000000..d60a9a285c
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/map.h b/toolkit/components/protobuf/src/google/protobuf/map.h
new file mode 100644
index 0000000000..008c192253
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/map.h
@@ -0,0 +1,1448 @@
+// 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__)
+#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/port.h>
+#include <google/protobuf/stubs/hash.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+// Must be included last.
+#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()) {}
+
+ // MapAllocator does not support alignments beyond 8. Technically we should
+ // support up to std::max_align_t, but this fails with ubsan and tcmalloc
+ // debug allocation logic which assume 8 as default alignment.
+ static_assert(alignof(value_type) <= 8, "");
+
+ 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) {
+ internal::SizedDelete(p, n * sizeof(value_type));
+ }
+ }
+
+#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 std::string
+// 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<std::string> {
+ 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
+ // std::string first.
+ // The template makes this overload lose resolution when both have the same
+ // rank otherwise.
+ template <typename = void>
+ static std::string_view ImplicitConvert(const std::string& 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 std::string& 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 std::string.
+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 PROTOBUF_ATTRIBUTE_STANDALONE_DEBUG 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;
+ }
+
+ // Inserts a new element into the container if there is no element with the
+ // key in the container.
+ // The new element is:
+ // (1) Constructed in-place with the given args, if mapped_type is not
+ // arena constructible.
+ // (2) Constructed in-place with the arena and then assigned with a
+ // mapped_type temporary constructed with the given args, otherwise.
+ template <typename K, typename... Args>
+ std::pair<iterator, bool> try_emplace(K&& k, Args&&... args) {
+ return ArenaAwareTryEmplace(Arena::is_arena_constructable<mapped_type>(),
+ std::forward<K>(k),
+ std::forward<Args>(args)...);
+ }
+
+ // Inserts 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) {
+ return try_emplace(std::forward<K>(k));
+ }
+
+ template <typename K>
+ value_type& operator[](K&& k) {
+ return *try_emplace(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:
+ template <typename K, typename... Args>
+ std::pair<iterator, bool> TryEmplaceInternal(K&& k, Args&&... args) {
+ 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.
+ // Note: This only works if `Key` is not arena constructible.
+ Arena::CreateInArenaStorage(const_cast<Key*>(&node->kv.first),
+ alloc_.arena(),
+ static_cast<TypeToInit>(std::forward<K>(k)));
+ // Note: if `T` is arena constructible, `Args` needs to be empty.
+ Arena::CreateInArenaStorage(&node->kv.second, alloc_.arena(),
+ std::forward<Args>(args)...);
+
+ iterator result = InsertUnique(b, node);
+ ++num_elements_;
+ return std::make_pair(result, true);
+ }
+
+ // A helper function to perform an assignment of `mapped_type`.
+ // If the first argument is true, then it is a regular assignment.
+ // Otherwise, we first create a temporary and then perform an assignment.
+ template <typename V>
+ static void AssignMapped(std::true_type, mapped_type& mapped, V&& v) {
+ mapped = std::forward<V>(v);
+ }
+ template <typename... Args>
+ static void AssignMapped(std::false_type, mapped_type& mapped,
+ Args&&... args) {
+ mapped = mapped_type(std::forward<Args>(args)...);
+ }
+
+ // Case 1: `mapped_type` is arena constructible. A temporary object is
+ // created and then (if `Args` are not empty) assigned to a mapped value
+ // that was created with the arena.
+ template <typename K>
+ std::pair<iterator, bool> ArenaAwareTryEmplace(std::true_type, K&& k) {
+ // case 1.1: "default" constructed (e.g. from arena only).
+ return TryEmplaceInternal(std::forward<K>(k));
+ }
+ template <typename K, typename... Args>
+ std::pair<iterator, bool> ArenaAwareTryEmplace(std::true_type, K&& k,
+ Args&&... args) {
+ // case 1.2: "default" constructed + copy/move assignment
+ auto p = TryEmplaceInternal(std::forward<K>(k));
+ if (p.second) {
+ AssignMapped(std::is_same<void(typename std::decay<Args>::type...),
+ void(mapped_type)>(),
+ p.first->second, std::forward<Args>(args)...);
+ }
+ return p;
+ }
+ // Case 2: `mapped_type` is not arena constructible. Using in-place
+ // construction.
+ template <typename... Args>
+ std::pair<iterator, bool> ArenaAwareTryEmplace(std::false_type,
+ Args&&... args) {
+ return TryEmplaceInternal(std::forward<Args>(args)...);
+ }
+
+ 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.
+ uint64_t 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 uint64_t kPhi = uint64_t{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__)
+ uint32_t hi, lo;
+ asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
+ s += ((static_cast<uint64_t>(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.
+ uint64_t 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
+ template <typename K, typename... Args>
+ std::pair<iterator, bool> try_emplace(K&& k, Args&&... args) {
+ auto p =
+ elements_.try_emplace(std::forward<K>(k), std::forward<Args>(args)...);
+ return std::pair<iterator, bool>(iterator(p.first), p.second);
+ }
+ std::pair<iterator, bool> insert(const value_type& value) {
+ return try_emplace(value.first, value.second);
+ }
+ std::pair<iterator, bool> insert(value_type&& value) {
+ return try_emplace(value.first, std::move(value.second));
+ }
+ template <typename... Args>
+ std::pair<iterator, bool> emplace(Args&&... args) {
+ return insert(value_type(std::forward<Args>(args)...));
+ }
+ template <class InputIt>
+ void insert(InputIt first, InputIt last) {
+ for (; first != last; ++first) {
+ try_emplace(first->first, first->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/toolkit/components/protobuf/src/google/protobuf/map_entry.h b/toolkit/components/protobuf/src/google/protobuf/map_entry.h
new file mode 100644
index 0000000000..536dec9d0d
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/map_entry.h
@@ -0,0 +1,134 @@
+// 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/port.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/reflection_ops.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/wire_format_lite.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 {
+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
+// int32_t TYPE_INT32 int32_t int32_t
+// int32_t TYPE_FIXED32 int32_t int32_t
+// 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() {}
+ explicit MapEntry(Arena* arena)
+ : MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
+ kValueFieldType>(arena) {}
+ ~MapEntry() override {
+ Message::_internal_metadata_.template 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;
+ }
+
+ 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);
+};
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_MAP_ENTRY_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/map_entry_lite.h b/toolkit/components/protobuf/src/google/protobuf/map_entry_lite.h
new file mode 100644
index 0000000000..6b08cd92ba
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/map_entry_lite.h
@@ -0,0 +1,563 @@
+// 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 <algorithm>
+#include <string>
+#include <utility>
+
+#include <google/protobuf/stubs/casts.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/port.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/parse_context.h>
+#include <google/protobuf/wire_format_lite.h>
+
+// Must be included last.
+#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);
+ }
+};
+
+// 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() override {
+ 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.
+ std::string 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)) {
+ uint32_t 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<std::string*>(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_;
+ }
+
+ 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),
+ uint32_t 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(); }
+
+ protected: // Needed for constructing tables
+ KeyOnMemory key_;
+ ValueOnMemory value_;
+ uint32_t _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() override {
+ MessageLite::_internal_metadata_.template Delete<std::string>();
+ }
+ void MergeFrom(const MapEntryLite& other) { MergeFromInternal(other); }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite);
+};
+
+// Helpers for deterministic serialization =============================
+
+// Iterator base for MapSorterFlat and MapSorterPtr.
+template <typename storage_type>
+struct MapSorterIt {
+ storage_type* ptr;
+ MapSorterIt(storage_type* ptr) : ptr(ptr) {}
+ bool operator==(const MapSorterIt& other) const { return ptr == other.ptr; }
+ bool operator!=(const MapSorterIt& other) const { return !(*this == other); }
+ MapSorterIt& operator++() { ++ptr; return *this; }
+ MapSorterIt operator++(int) { auto other = *this; ++ptr; return other; }
+ MapSorterIt operator+(int v) { return MapSorterIt{ptr + v}; }
+};
+
+// MapSorterFlat stores keys inline with pointers to map entries, so that
+// keys can be compared without indirection. This type is used for maps with
+// keys that are not strings.
+template <typename MapT>
+class MapSorterFlat {
+ public:
+ using value_type = typename MapT::value_type;
+ using storage_type = std::pair<typename MapT::key_type, const value_type*>;
+
+ // This const_iterator dereferenes to the map entry stored in the sorting
+ // array pairs. This is the same interface as the Map::const_iterator type,
+ // and allows generated code to use the same loop body with either form:
+ // for (const auto& entry : map) { ... }
+ // for (const auto& entry : MapSorterFlat(map)) { ... }
+ struct const_iterator : public MapSorterIt<storage_type> {
+ using pointer = const typename MapT::value_type*;
+ using reference = const typename MapT::value_type&;
+ using MapSorterIt<storage_type>::MapSorterIt;
+
+ pointer operator->() const { return this->ptr->second; }
+ reference operator*() const { return *this->operator->(); }
+ };
+
+ explicit MapSorterFlat(const MapT& m)
+ : size_(m.size()), items_(size_ ? new storage_type[size_] : nullptr) {
+ if (!size_) return;
+ storage_type* it = &items_[0];
+ for (const auto& entry : m) {
+ *it++ = {entry.first, &entry};
+ }
+ std::sort(&items_[0], &items_[size_],
+ [](const storage_type& a, const storage_type& b) {
+ return a.first < b.first;
+ });
+ }
+ size_t size() const { return size_; }
+ const_iterator begin() const { return {items_.get()}; }
+ const_iterator end() const { return {items_.get() + size_}; }
+
+ private:
+ size_t size_;
+ std::unique_ptr<storage_type[]> items_;
+};
+
+// MapSorterPtr stores and sorts pointers to map entries. This type is used for
+// maps with keys that are strings.
+template <typename MapT>
+class MapSorterPtr {
+ public:
+ using value_type = typename MapT::value_type;
+ using storage_type = const typename MapT::value_type*;
+
+ // This const_iterator dereferenes the map entry pointer stored in the sorting
+ // array. This is the same interface as the Map::const_iterator type, and
+ // allows generated code to use the same loop body with either form:
+ // for (const auto& entry : map) { ... }
+ // for (const auto& entry : MapSorterPtr(map)) { ... }
+ struct const_iterator : public MapSorterIt<storage_type> {
+ using pointer = const typename MapT::value_type*;
+ using reference = const typename MapT::value_type&;
+ using MapSorterIt<storage_type>::MapSorterIt;
+
+ pointer operator->() const { return *this->ptr; }
+ reference operator*() const { return *this->operator->(); }
+ };
+
+ explicit MapSorterPtr(const MapT& m)
+ : size_(m.size()), items_(size_ ? new storage_type[size_] : nullptr) {
+ if (!size_) return;
+ storage_type* it = &items_[0];
+ for (const auto& entry : m) {
+ *it++ = &entry;
+ }
+ std::sort(&items_[0], &items_[size_],
+ [](const storage_type& a, const storage_type& b) {
+ return a->first < b->first;
+ });
+ }
+ size_t size() const { return size_; }
+ const_iterator begin() const { return {items_.get()}; }
+ const_iterator end() const { return {items_.get() + size_}; }
+
+ private:
+ size_t size_;
+ std::unique_ptr<storage_type[]> items_;
+};
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/map_field.cc b/toolkit/components/protobuf/src/google/protobuf/map_field.cc
new file mode 100644
index 0000000000..ed662dfc43
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/map_field.cc
@@ -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.
+
+#include <google/protobuf/map_field.h>
+
+#include <vector>
+
+#include <google/protobuf/map_field_inl.h>
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+void MapFieldBase::Destruct() {
+ if (arena_ == nullptr) {
+ delete repeated_field_;
+ }
+ repeated_field_ = nullptr;
+}
+
+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) {
+ // DynamicMapField owns map values. Need to delete them before clearing the
+ // map.
+ for (auto& kv : map_) {
+ kv.second.DeleteData();
+ }
+ map_.clear();
+ }
+ Destruct();
+}
+
+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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE(FLOAT, float);
+ HANDLE_TYPE(BOOL, bool);
+ HANDLE_TYPE(STRING, std::string);
+ HANDLE_TYPE(ENUM, int32_t);
+#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, int32_t, Int32);
+ HANDLE_TYPE(INT64, int64_t, Int64);
+ HANDLE_TYPE(UINT32, uint32_t, UInt32);
+ HANDLE_TYPE(UINT64, uint64_t, UInt64);
+ HANDLE_TYPE(DOUBLE, double, Double);
+ HANDLE_TYPE(FLOAT, float, Float);
+ HANDLE_TYPE(BOOL, bool, Bool);
+ HANDLE_TYPE(STRING, std::string, String);
+ HANDLE_TYPE(ENUM, int32_t, 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(std::string) * 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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE(FLOAT, float);
+ HANDLE_TYPE(BOOL, bool);
+ HANDLE_TYPE(STRING, std::string);
+ HANDLE_TYPE(ENUM, int32_t);
+#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/toolkit/components/protobuf/src/google/protobuf/map_field.h b/toolkit/components/protobuf/src/google/protobuf/map_field.h
new file mode 100644
index 0000000000..287d58f312
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/map_field.h
@@ -0,0 +1,946 @@
+// 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/stubs/mutex.h>
+#include <google/protobuf/port.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/repeated_field.h>
+#include <google/protobuf/unknown_field_set.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 DynamicMessage;
+class MapIterator;
+
+// Microsoft compiler complains about non-virtual destructor,
+// even when the destructor is private.
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4265)
+#endif // _MSC_VER
+
+#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(int64_t value) {
+ SetType(FieldDescriptor::CPPTYPE_INT64);
+ val_.int64_value_ = value;
+ }
+ void SetUInt64Value(uint64_t value) {
+ SetType(FieldDescriptor::CPPTYPE_UINT64);
+ val_.uint64_value_ = value;
+ }
+ void SetInt32Value(int32_t value) {
+ SetType(FieldDescriptor::CPPTYPE_INT32);
+ val_.int32_value_ = value;
+ }
+ void SetUInt32Value(uint32_t value) {
+ SetType(FieldDescriptor::CPPTYPE_UINT32);
+ val_.uint32_value_ = value;
+ }
+ void SetBoolValue(bool value) {
+ SetType(FieldDescriptor::CPPTYPE_BOOL);
+ val_.bool_value_ = value;
+ }
+ void SetStringValue(std::string val) {
+ SetType(FieldDescriptor::CPPTYPE_STRING);
+ *val_.string_value_.get_mutable() = std::move(val);
+ }
+
+ int64_t GetInt64Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapKey::GetInt64Value");
+ return val_.int64_value_;
+ }
+ uint64_t GetUInt64Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapKey::GetUInt64Value");
+ return val_.uint64_value_;
+ }
+ int32_t GetInt32Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapKey::GetInt32Value");
+ return val_.int32_value_;
+ }
+ uint32_t 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 std::string& 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<std::string> string_value_;
+ int64_t int64_value_;
+ int32_t int32_value_;
+ uint64_t uint64_value_;
+ uint32_t 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<std::string>()(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.
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ 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) {}
+
+ protected:
+ ~MapFieldBase() { // "protected" stops users from deleting a `MapFieldBase *`
+ GOOGLE_DCHECK(repeated_field_ == nullptr);
+ }
+ void Destruct();
+
+ public:
+ // 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.
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ constexpr TypeDefinedMapFieldBase(ConstantInitialized tag)
+ : MapFieldBase(tag) {}
+ explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
+ TypeDefinedMapFieldBase(ArenaInitialized, Arena* arena)
+ : TypeDefinedMapFieldBase(arena) {}
+
+ protected:
+ ~TypeDefinedMapFieldBase() {}
+ using MapFieldBase::Destruct;
+
+ public:
+ 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 Map<Key, T> MapType;
+
+ MapField() : impl_() {}
+ virtual ~MapField() {} // Destruct() must already have been called!
+ void Destruct() {
+ impl_.Destruct();
+ TypeDefinedMapFieldBase<Key, T>::Destruct();
+ }
+
+ // This constructor is for constant initialized global instances.
+ // It uses a linker initialized mutex, so it is not compatible with regular
+ // runtime instances.
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ constexpr MapField(ConstantInitialized tag)
+ : TypeDefinedMapFieldBase<Key, T>(tag), impl_() {}
+ explicit MapField(Arena* arena)
+ : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {}
+ MapField(ArenaInitialized, Arena* arena) : MapField(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(); }
+
+ 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), uint32_t 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);
+ virtual ~DynamicMapField();
+
+ // 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_() {}
+
+ int64_t GetInt64Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
+ "MapValueConstRef::GetInt64Value");
+ return *reinterpret_cast<int64_t*>(data_);
+ }
+ uint64_t GetUInt64Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
+ "MapValueConstRef::GetUInt64Value");
+ return *reinterpret_cast<uint64_t*>(data_);
+ }
+ int32_t GetInt32Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
+ "MapValueConstRef::GetInt32Value");
+ return *reinterpret_cast<int32_t*>(data_);
+ }
+ uint32_t GetUInt32Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
+ "MapValueConstRef::GetUInt32Value");
+ return *reinterpret_cast<uint32_t*>(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 std::string& GetStringValue() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
+ "MapValueConstRef::GetStringValue");
+ return *reinterpret_cast<std::string*>(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(int64_t value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::SetInt64Value");
+ *reinterpret_cast<int64_t*>(data_) = value;
+ }
+ void SetUInt64Value(uint64_t value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::SetUInt64Value");
+ *reinterpret_cast<uint64_t*>(data_) = value;
+ }
+ void SetInt32Value(int32_t value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::SetInt32Value");
+ *reinterpret_cast<int32_t*>(data_) = value;
+ }
+ void SetUInt32Value(uint32_t value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::SetUInt32Value");
+ *reinterpret_cast<uint32_t*>(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 std::string& value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapValueRef::SetStringValue");
+ *reinterpret_cast<std::string*>(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, int32_t);
+ HANDLE_TYPE(INT64, int64_t);
+ HANDLE_TYPE(UINT32, uint32_t);
+ HANDLE_TYPE(UINT64, uint64_t);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE(FLOAT, float);
+ HANDLE_TYPE(BOOL, bool);
+ HANDLE_TYPE(STRING, std::string);
+ HANDLE_TYPE(ENUM, int32_t);
+ 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()->map_key()->cpp_type());
+ value_.SetType(field->message_type()->map_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
+
+#ifdef _MSC_VER
+#pragma warning(pop) // restore warning C4265
+#endif // _MSC_VER
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_MAP_FIELD_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/map_field_inl.h b/toolkit/components/protobuf/src/google/protobuf/map_field_inl.h
new file mode 100644
index 0000000000..7c4c2323c4
--- /dev/null
+++ b/toolkit/components/protobuf/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 int32_t UnwrapMapKey<int32_t>(const MapKey& map_key) {
+ return map_key.GetInt32Value();
+}
+template <>
+inline uint32_t UnwrapMapKey<uint32_t>(const MapKey& map_key) {
+ return map_key.GetUInt32Value();
+}
+template <>
+inline int64_t UnwrapMapKey<int64_t>(const MapKey& map_key) {
+ return map_key.GetInt64Value();
+}
+template <>
+inline uint64_t UnwrapMapKey<uint64_t>(const MapKey& map_key) {
+ return map_key.GetUInt64Value();
+}
+template <>
+inline bool UnwrapMapKey<bool>(const MapKey& map_key) {
+ return map_key.GetBoolValue();
+}
+template <>
+inline std::string UnwrapMapKey<std::string>(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<int32_t>(MapKey* map_key, const int32_t& value) {
+ map_key->SetInt32Value(value);
+}
+template <>
+inline void SetMapKey<uint32_t>(MapKey* map_key, const uint32_t& value) {
+ map_key->SetUInt32Value(value);
+}
+template <>
+inline void SetMapKey<int64_t>(MapKey* map_key, const int64_t& value) {
+ map_key->SetInt64Value(value);
+}
+template <>
+inline void SetMapKey<uint64_t>(MapKey* map_key, const uint64_t& value) {
+ map_key->SetUInt64Value(value);
+}
+template <>
+inline void SetMapKey<bool>(MapKey* map_key, const bool& value) {
+ map_key->SetBoolValue(value);
+}
+template <>
+inline void SetMapKey<std::string>(MapKey* map_key, const std::string& 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/toolkit/components/protobuf/src/google/protobuf/map_field_lite.h b/toolkit/components/protobuf/src/google/protobuf/map_field_lite.h
new file mode 100644
index 0000000000..53bf7a0811
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/map_field_lite.h
@@ -0,0 +1,209 @@
+// 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/io/coded_stream.h>
+#include <google/protobuf/port.h>
+#include <google/protobuf/map.h>
+#include <google/protobuf/map_entry_lite.h>
+#include <google/protobuf/parse_context.h>
+#include <google/protobuf/wire_format_lite.h>
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+#ifndef NDEBUG
+void MapFieldLiteNotDestructed(void* map_field_lite);
+#endif
+
+// 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;
+
+ constexpr MapFieldLite() : map_() {}
+ explicit MapFieldLite(Arena* arena) : map_(arena) {}
+ MapFieldLite(ArenaInitialized, Arena* arena) : MapFieldLite(arena) {}
+
+#ifdef NDEBUG
+ void Destruct() { map_.~Map(); }
+ ~MapFieldLite() {}
+#else
+ void Destruct() {
+ // We want to destruct the map in such a way that we can verify
+ // that we've done that, but also be sure that we've deallocated
+ // everything (as opposed to leaving an allocation behind with no
+ // data in it, as would happen if a vector was resize'd to zero.
+ // Map::Swap with an empty map accomplishes that.
+ decltype(map_) swapped_map(map_.arena());
+ map_.InternalSwap(swapped_map);
+ }
+ ~MapFieldLite() {
+ if (map_.arena() == nullptr && !map_.empty()) {
+ MapFieldLiteNotDestructed(this);
+ }
+ }
+#endif
+ // 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());
+ }
+
+ 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), uint32_t 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_ is inside an anonymous union so we can explicitly control its
+ // destruction
+ union {
+ 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);
+ uint32_t 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), uint32_t 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;
+};
+
+#ifndef NDEBUG
+inline PROTOBUF_NOINLINE void MapFieldLiteNotDestructed(void* map_field_lite) {
+ bool proper_destruct = false;
+ GOOGLE_CHECK(proper_destruct) << map_field_lite;
+}
+#endif
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/map_type_handler.h b/toolkit/components/protobuf/src/google/protobuf/map_type_handler.h
new file mode 100644
index 0000000000..c210c63db5
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/map_type_handler.h
@@ -0,0 +1,736 @@
+// 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/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/parse_context.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, int64_t, VARINT, false, false)
+TYPE_TRAITS(UINT64, uint64_t, VARINT, false, false)
+TYPE_TRAITS(INT32, int32_t, VARINT, false, false)
+TYPE_TRAITS(UINT32, uint32_t, VARINT, false, false)
+TYPE_TRAITS(SINT64, int64_t, VARINT, false, false)
+TYPE_TRAITS(SINT32, int32_t, 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, uint64_t, FIXED64, false, false)
+TYPE_TRAITS(FIXED32, uint32_t, FIXED32, false, false)
+TYPE_TRAITS(SFIXED64, int64_t, FIXED64, false, false)
+TYPE_TRAITS(SFIXED32, int32_t, 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, value.GetCachedSize(), 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, int64_t* value) {
+ return VarintParse(ptr, reinterpret_cast<uint64_t*>(value));
+}
+inline const char* ReadUINT64(const char* ptr, uint64_t* value) {
+ return VarintParse(ptr, value);
+}
+inline const char* ReadINT32(const char* ptr, int32_t* value) {
+ return VarintParse(ptr, reinterpret_cast<uint32_t*>(value));
+}
+inline const char* ReadUINT32(const char* ptr, uint32_t* value) {
+ return VarintParse(ptr, value);
+}
+inline const char* ReadSINT64(const char* ptr, int64_t* value) {
+ *value = ReadVarintZigZag64(&ptr);
+ return ptr;
+}
+inline const char* ReadSINT32(const char* ptr, int32_t* 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, uint64_t* value) {
+ return ReadUnaligned(ptr, value);
+}
+inline const char* ReadFIXED32(const char* ptr, uint32_t* value) {
+ return ReadUnaligned(ptr, value);
+}
+inline const char* ReadSFIXED64(const char* ptr, int64_t* value) {
+ return ReadUnaligned(ptr, value);
+}
+inline const char* ReadSFIXED32(const char* ptr, int32_t* 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(from, arena); \
+ } \
+ template <typename Type> \
+ void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::DeleteNoArena( \
+ TypeOnMemory& value) { \
+ value.Destroy(); \
+ } \
+ template <typename Type> \
+ constexpr auto \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Constinit() \
+ ->TypeOnMemory { \
+ return TypeOnMemory(&internal::fixed_address_empty_string, \
+ ConstantInitialized{}); \
+ } \
+ template <typename Type> \
+ inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::MapEntryAccessorType* \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable( \
+ TypeOnMemory* value, Arena* arena) { \
+ return value->Mutable(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
+
+// Functions for operating on a map entry using type handlers.
+//
+// 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;
+ enum : int {
+ kKeyFieldNumber = 1,
+ 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<uint32_t>(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);
+ }
+};
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_MAP_TYPE_HANDLER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/message.cc b/toolkit/components/protobuf/src/google/protobuf/message.cc
new file mode 100644
index 0000000000..6cdc6c8393
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/message.cc
@@ -0,0 +1,404 @@
+// 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/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.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/parse_context.h>
+#include <google/protobuf/reflection_internal.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/map_util.h>
+#include <google/protobuf/stubs/stl_util.h>
+#include <google/protobuf/stubs/hash.h>
+
+// Must be included last.
+#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::CopyWithSourceCheck(Message& to, const Message& from) {
+#ifndef NDEBUG
+ FailIfCopyFromDescendant(to, from);
+#endif
+ to.Clear();
+ to.GetClassData()->merge_to_from(to, from);
+}
+
+void Message::FailIfCopyFromDescendant(Message& to, const Message& from) {
+ auto* arena = to.GetArenaForAllocation();
+ bool same_message_owned_arena = to.GetOwningArena() == nullptr &&
+ arena != nullptr &&
+ arena == from.GetOwningArena();
+ GOOGLE_CHECK(!same_message_owned_arena && !internal::IsDescendant(to, from))
+ << "Source of CopyFrom cannot be a descendant of the target.";
+}
+
+std::string 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<std::string>* errors) const {
+ return ReflectionOps::FindInitializationErrors(*this, "", errors);
+}
+
+std::string Message::InitializationErrorString() const {
+ std::vector<std::string> 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);
+}
+
+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);
+}
+
+uint64_t Message::GetInvariantPerBuild(uint64_t 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, int32_t)
+ HANDLE_PRIMITIVE_TYPE(UINT32, uint32_t)
+ HANDLE_PRIMITIVE_TYPE(INT64, int64_t)
+ HANDLE_PRIMITIVE_TYPE(UINT64, uint64_t)
+ HANDLE_PRIMITIVE_TYPE(FLOAT, float)
+ HANDLE_PRIMITIVE_TYPE(DOUBLE, double)
+ HANDLE_PRIMITIVE_TYPE(BOOL, bool)
+ HANDLE_PRIMITIVE_TYPE(ENUM, int32_t)
+#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/toolkit/components/protobuf/src/google/protobuf/message.h b/toolkit/components/protobuf/src/google/protobuf/message.h
new file mode 100644
index 0000000000..39ec154c34
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/message.h
@@ -0,0 +1,1497 @@
+// 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:
+//
+// std::string 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/port.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/map.h> // TODO(b/211442718): cleanup
+#include <google/protobuf/message_lite.h>
+
+
+// Must be included last.
+#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 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, uint32_t offset) {
+ return reinterpret_cast<To*>(reinterpret_cast<char*>(message) + offset);
+}
+
+template <class To>
+const To* GetConstPointerAtOffset(const Message* message, uint32_t offset) {
+ return reinterpret_cast<const To*>(reinterpret_cast<const char*>(message) +
+ offset);
+}
+
+template <class To>
+const To& GetConstRefAtOffset(const Message& message, uint32_t offset) {
+ return *GetConstPointerAtOffset<To>(&message, offset);
+}
+
+bool CreateUnknownEnumValues(const FieldDescriptor* field);
+
+// Returns true if "message" is a descendant of "root".
+PROTOBUF_EXPORT bool IsDescendant(Message& root, const Message& message);
+} // 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);".
+ 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<std::string>* errors) const;
+
+ // Like FindInitializationErrors, but joins all the strings, delimited by
+ // commas, and returns them.
+ std::string 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 for debugging purposes.
+ // Note that the format and content of a debug string is not guaranteed, may
+ // change without notice, and should not be depended on. Code that does
+ // anything except display a string to assist in debugging should use
+ // TextFormat instead.
+ std::string DebugString() const;
+ // Like DebugString(), but with less whitespace.
+ std::string ShortDebugString() const;
+ // Like DebugString(), but do not escape UTF-8 byte sequences.
+ std::string 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.
+
+ std::string 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;
+
+ 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; }
+
+ // CopyWithSourceCheck calls Clear() and then MergeFrom(), and in debug
+ // builds, checks that calling Clear() on the destination message doesn't
+ // alter the source. It assumes the messages are known to be of the same
+ // type, and thus uses GetClassData().
+ static void CopyWithSourceCheck(Message& to, const Message& from);
+
+ // Fail if "from" is a descendant of "to" as such copy is not allowed.
+ static void FailIfCopyFromDescendant(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 uint64_t GetInvariantPerBuild(uint64_t 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.
+
+ int32_t GetInt32(const Message& message, const FieldDescriptor* field) const;
+ int64_t GetInt64(const Message& message, const FieldDescriptor* field) const;
+ uint32_t GetUInt32(const Message& message,
+ const FieldDescriptor* field) const;
+ uint64_t 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;
+ std::string 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 std::string is already stored in a std::string object
+ // in the underlying message. GetStringReference() will return a reference to
+ // the underlying std::string 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:
+ // std::string str = reflection->GetString(message, field);
+ const std::string& GetStringReference(const Message& message,
+ const FieldDescriptor* field,
+ std::string* scratch) const;
+
+
+ // Singular field mutators -----------------------------------------
+ // These mutate the value of a non-repeated field.
+
+ void SetInt32(Message* message, const FieldDescriptor* field,
+ int32_t value) const;
+ void SetInt64(Message* message, const FieldDescriptor* field,
+ int64_t value) const;
+ void SetUInt32(Message* message, const FieldDescriptor* field,
+ uint32_t value) const;
+ void SetUInt64(Message* message, const FieldDescriptor* field,
+ uint64_t 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,
+ std::string 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.
+
+ int32_t GetRepeatedInt32(const Message& message, const FieldDescriptor* field,
+ int index) const;
+ int64_t GetRepeatedInt64(const Message& message, const FieldDescriptor* field,
+ int index) const;
+ uint32_t GetRepeatedUInt32(const Message& message,
+ const FieldDescriptor* field, int index) const;
+ uint64_t 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;
+ std::string 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 std::string& GetRepeatedStringReference(const Message& message,
+ const FieldDescriptor* field,
+ int index,
+ std::string* 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, int32_t value) const;
+ void SetRepeatedInt64(Message* message, const FieldDescriptor* field,
+ int index, int64_t value) const;
+ void SetRepeatedUInt32(Message* message, const FieldDescriptor* field,
+ int index, uint32_t value) const;
+ void SetRepeatedUInt64(Message* message, const FieldDescriptor* field,
+ int index, uint64_t 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, std::string 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,
+ int32_t value) const;
+ void AddInt64(Message* message, const FieldDescriptor* field,
+ int64_t value) const;
+ void AddUInt32(Message* message, const FieldDescriptor* field,
+ uint32_t value) const;
+ void AddUInt64(Message* message, const FieldDescriptor* field,
+ uint64_t 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,
+ std::string 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 int32_t
+ // CPPTYPE_UINT32 uint32_t
+ // CPPTYPE_INT64 int64_t
+ // CPPTYPE_UINT64 uint64_t
+ // CPPTYPE_DOUBLE double
+ // CPPTYPE_FLOAT float
+ // CPPTYPE_BOOL bool
+ // CPPTYPE_ENUM generated enum type or int32_t
+ // CPPTYPE_STRING std::string
+ // 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 = std::string, 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 = std::string, 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 std::string& 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;
+ friend bool internal::IsDescendant(Message& root, const Message& message);
+
+ 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 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 uint32_t* GetHasBits(const Message& message) const;
+ inline uint32_t* MutableHasBits(Message* message) const;
+ inline uint32_t GetOneofCase(const Message& message,
+ const OneofDescriptor* oneof_descriptor) const;
+ inline uint32_t* 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;
+
+ 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 uint32_t* GetInlinedStringDonatedArray(
+ const Message& message) const;
+ inline uint32_t* MutableInlinedStringDonatedArray(Message* message) const;
+ inline bool IsInlinedStringDonated(const Message& message,
+ const FieldDescriptor* field) const;
+ inline void SwapInlinedStringDonated(Message* lhs, Message* rhs,
+ 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(int32_t)
+DECLARE_GET_REPEATED_FIELD(int64_t)
+DECLARE_GET_REPEATED_FIELD(uint32_t)
+DECLARE_GET_REPEATED_FIELD(uint64_t)
+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<pkg::FooMessage>();
+//
+// This will ensure that the following lookup will succeed:
+//
+// DescriptorPool::generated_pool()->FindMessageTypeByName("pkg.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 <std::string>, <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<std::string>&
+Reflection::GetRepeatedPtrFieldInternal<std::string>(
+ const Message& message, const FieldDescriptor* field) const {
+ return *static_cast<RepeatedPtrField<std::string>*>(
+ MutableRawRepeatedString(const_cast<Message*>(&message), field, true));
+}
+
+template <>
+inline RepeatedPtrField<std::string>*
+Reflection::MutableRepeatedPtrFieldInternal<std::string>(
+ Message* message, const FieldDescriptor* field) const {
+ return static_cast<RepeatedPtrField<std::string>*>(
+ 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));
+}
+
+uint32_t Reflection::GetOneofCase(
+ const Message& message, const OneofDescriptor* oneof_descriptor) const {
+ GOOGLE_DCHECK(!oneof_descriptor->is_synthetic());
+ return internal::GetConstRefAtOffset<uint32_t>(
+ message, schema_.GetOneofCaseOffset(oneof_descriptor));
+}
+
+bool Reflection::HasOneofField(const Message& message,
+ const FieldDescriptor* field) const {
+ return (GetOneofCase(message, field->containing_oneof()) ==
+ static_cast<uint32_t>(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/toolkit/components/protobuf/src/google/protobuf/message_lite.cc b/toolkit/components/protobuf/src/google/protobuf/message_lite.cc
new file mode 100644
index 0000000000..a1790b167f
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/message_lite.cc
@@ -0,0 +1,603 @@
+// 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 <istream>
+
+#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/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/stubs/stl_util.h>
+#include <google/protobuf/stubs/mutex.h>
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+std::string MessageLite::InitializationErrorString() const {
+ return "(cannot determine missing fields for lite message)";
+}
+
+std::string 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.";
+}
+
+std::string 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());
+
+ std::string 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;
+}
+
+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_NE(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<int64_t>(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(std::string* output) const {
+ GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
+ return AppendPartialToString(output);
+}
+
+bool MessageLite::AppendPartialToString(std::string* 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(std::string* output) const {
+ output->clear();
+ return AppendToString(output);
+}
+
+bool MessageLite::SerializePartialToString(std::string* 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<int64_t>(byte_size)) return false;
+ uint8_t* start = reinterpret_cast<uint8_t*>(data);
+ SerializeToArrayImpl(*this, start, byte_size);
+ return true;
+}
+
+std::string 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.
+ std::string output;
+ if (!AppendToString(&output)) output.clear();
+ return output;
+}
+
+std::string MessageLite::SerializePartialAsString() const {
+ std::string output;
+ if (!AppendPartialToString(&output)) output.clear();
+ return output;
+}
+
+
+namespace internal {
+
+MessageLite* NewFromPrototypeHelper(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<std::string>::Merge(const std::string& from,
+ std::string* to) {
+ *to = from;
+}
+
+// Non-inline implementations of InternalMetadata destructor
+// This is moved out of the header because the GOOGLE_DCHECK produces a lot of code.
+void InternalMetadata::CheckedDestruct() {
+ if (HasMessageOwnedArenaTag()) {
+ GOOGLE_DCHECK(!HasUnknownFieldsTag());
+ delete reinterpret_cast<Arena*>(ptr_ - kMessageOwnedArenaTagMask);
+ }
+}
+
+// Non-inline variants of std::string specializations for
+// various InternalMetadata routines.
+template <>
+void InternalMetadata::DoClear<std::string>() {
+ mutable_unknown_fields<std::string>()->clear();
+}
+
+template <>
+void InternalMetadata::DoMergeFrom<std::string>(const std::string& other) {
+ mutable_unknown_fields<std::string>()->append(other);
+}
+
+template <>
+void InternalMetadata::DoSwap<std::string>(std::string* other) {
+ mutable_unknown_fields<std::string>()->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/toolkit/components/protobuf/src/google/protobuf/message_lite.h b/toolkit/components/protobuf/src/google/protobuf/message_lite.h
new file mode 100644
index 0000000000..950ae1a126
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/message_lite.h
@@ -0,0 +1,591 @@
+// 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__
+
+
+#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/stubs/once.h>
+#include <google/protobuf/port.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/explicitly_constructed.h>
+#include <google/protobuf/metadata_lite.h>
+#include <google/protobuf/stubs/hash.h> // TODO(b/211442718): cleanup
+
+// 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;
+
+// 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. This empty string is aligned with a
+// minimum alignment of 8 bytes to match the requirement of ArenaStringPtr.
+PROTOBUF_EXPORT extern ExplicitlyConstructedArenaString
+ fixed_address_empty_string;
+
+
+PROTOBUF_EXPORT constexpr const std::string& GetEmptyStringAlreadyInited() {
+ return fixed_address_empty_string.get();
+}
+
+PROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const std::string& 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 std::string 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;
+
+ // Returns user-owned arena; nullptr if it's message owned.
+ Arena* GetArena() const { return _internal_metadata_.user_arena(); }
+
+ // Clear all fields of the message and set them to their default values.
+ // Clear() assumes that any memory allocated to hold parts of the message
+ // will likely be needed again, so the memory used may not be freed.
+ // To ensure that all memory used by a Message is freed, 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 std::string 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.
+ std::string DebugString() const;
+ std::string ShortDebugString() const { return DebugString(); }
+ // MessageLite::DebugString is already Utf8 Safe. This is to add compatibility
+ // with Message.
+ std::string 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 bool ParseFromCodedStream(
+ io::CodedInputStream* input);
+ // Like ParseFromCodedStream(), but accepts messages that are missing
+ // required fields.
+ PROTOBUF_ATTRIBUTE_REINITIALIZES 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 bool ParseFromZeroCopyStream(
+ io::ZeroCopyInputStream* input);
+ // Like ParseFromZeroCopyStream(), but accepts messages that are missing
+ // required fields.
+ PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromZeroCopyStream(
+ io::ZeroCopyInputStream* input);
+ // Parse a protocol buffer from a file descriptor. If successful, the entire
+ // input will be consumed.
+ PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromFileDescriptor(
+ int file_descriptor);
+ // Like ParseFromFileDescriptor(), but accepts messages that are missing
+ // required fields.
+ PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromFileDescriptor(
+ int file_descriptor);
+ // Parse a protocol buffer from a C++ istream. If successful, the entire
+ // input will be consumed.
+ PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromIstream(std::istream* input);
+ // Like ParseFromIstream(), but accepts messages that are missing
+ // required fields.
+ PROTOBUF_ATTRIBUTE_REINITIALIZES 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.
+ bool MergePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input,
+ int size);
+ // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are
+ // missing required fields.
+ bool MergeFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size);
+ PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromBoundedZeroCopyStream(
+ io::ZeroCopyInputStream* input, int size);
+ // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are
+ // missing required fields.
+ PROTOBUF_ATTRIBUTE_REINITIALIZES 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 bool ParseFromString(ConstStringParam data);
+ // Like ParseFromString(), but accepts messages that are missing
+ // required fields.
+ PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromString(
+ ConstStringParam data);
+ // Parse a protocol buffer contained in an array of bytes.
+ PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromArray(const void* data,
+ int size);
+ // Like ParseFromArray(), but accepts messages that are missing
+ // required fields.
+ PROTOBUF_ATTRIBUTE_REINITIALIZES 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().
+ 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().
+ bool MergePartialFromCodedStream(io::CodedInputStream* input);
+
+ // Merge a protocol buffer contained in a string.
+ 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.
+ bool SerializeToCodedStream(io::CodedOutputStream* output) const;
+ // Like SerializeToCodedStream(), but allows missing required fields.
+ bool SerializePartialToCodedStream(io::CodedOutputStream* output) const;
+ // Write the message to the given zero-copy output stream. All required
+ // fields must be set.
+ bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const;
+ // Like SerializeToZeroCopyStream(), but allows missing required fields.
+ bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const;
+ // Serialize the message and store it in the given string. All required
+ // fields must be set.
+ bool SerializeToString(std::string* output) const;
+ // Like SerializeToString(), but allows missing required fields.
+ bool SerializePartialToString(std::string* output) const;
+ // Serialize the message and store it in the given byte array. All required
+ // fields must be set.
+ bool SerializeToArray(void* data, int size) const;
+ // Like SerializeToArray(), but allows missing required fields.
+ 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().
+ std::string SerializeAsString() const;
+ // Like SerializeAsString(), but allows missing required fields.
+ std::string SerializePartialAsString() const;
+
+ // Serialize the message and write it to the given file descriptor. All
+ // required fields must be set.
+ bool SerializeToFileDescriptor(int file_descriptor) const;
+ // Like SerializeToFileDescriptor(), but allows missing required fields.
+ bool SerializePartialToFileDescriptor(int file_descriptor) const;
+ // Serialize the message and write it to the given C++ ostream. All
+ // required fields must be set.
+ bool SerializeToOstream(std::ostream* output) const;
+ // Like SerializeToOstream(), but allows missing required fields.
+ 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.
+ bool AppendToString(std::string* output) const;
+ // Like AppendToString(), but allows missing required fields.
+ bool AppendPartialToString(std::string* 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;
+ }
+
+ virtual void OnDemandRegisterArenaDtor(Arena* /*arena*/) {}
+
+ 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(); }
+
+ // Returns true if this message is enabled for message-owned arena (MOA)
+ // trials. No lite messages are eligible for MOA.
+ static bool InMoaTrial() { return false; }
+
+ 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>
+ 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;
+ }
+
+ private:
+ 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;
+
+ bool MergeFromImpl(io::CodedInputStream* input, ParseFlags parse_flags);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite);
+};
+
+namespace internal {
+
+template <bool alias>
+bool MergeFromImpl(StringPiece input, MessageLite* msg,
+ MessageLite::ParseFlags parse_flags);
+extern template bool MergeFromImpl<false>(StringPiece input,
+ MessageLite* msg,
+ MessageLite::ParseFlags parse_flags);
+extern template bool MergeFromImpl<true>(StringPiece input,
+ MessageLite* msg,
+ MessageLite::ParseFlags parse_flags);
+
+template <bool alias>
+bool MergeFromImpl(io::ZeroCopyInputStream* input, MessageLite* msg,
+ MessageLite::ParseFlags parse_flags);
+extern template bool MergeFromImpl<false>(io::ZeroCopyInputStream* input,
+ MessageLite* msg,
+ MessageLite::ParseFlags parse_flags);
+extern template bool MergeFromImpl<true>(io::ZeroCopyInputStream* input,
+ MessageLite* msg,
+ MessageLite::ParseFlags parse_flags);
+
+struct BoundedZCIS {
+ io::ZeroCopyInputStream* zcis;
+ int limit;
+};
+
+template <bool alias>
+bool MergeFromImpl(BoundedZCIS input, MessageLite* msg,
+ MessageLite::ParseFlags parse_flags);
+extern template bool MergeFromImpl<false>(BoundedZCIS input, MessageLite* msg,
+ MessageLite::ParseFlags parse_flags);
+extern template bool MergeFromImpl<true>(BoundedZCIS input, MessageLite* msg,
+ MessageLite::ParseFlags parse_flags);
+
+template <typename T>
+struct SourceWrapper;
+
+template <bool alias, typename T>
+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/toolkit/components/protobuf/src/google/protobuf/metadata.h b/toolkit/components/protobuf/src/google/protobuf/metadata.h
new file mode 100644
index 0000000000..4e89648ee6
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/metadata.h
@@ -0,0 +1,36 @@
+// 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_H__
+#define GOOGLE_PROTOBUF_METADATA_H__
+
+// TODO(b/151117630): Remove this file and all instances where it gets imported.
+
+#endif // GOOGLE_PROTOBUF_METADATA_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/metadata_lite.h b/toolkit/components/protobuf/src/google/protobuf/metadata_lite.h
new file mode 100644
index 0000000000..0c31517f08
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/metadata_lite.h
@@ -0,0 +1,316 @@
+// 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>
+
+// Must be included last.
+#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 PROTOBUF_EXPORT InternalMetadata {
+ public:
+ constexpr InternalMetadata() : ptr_(0) {}
+ explicit InternalMetadata(Arena* arena, bool is_message_owned = false) {
+ SetArena(arena, is_message_owned);
+ }
+
+ void SetArena(Arena* arena, bool is_message_owned) {
+ ptr_ = is_message_owned
+ ? reinterpret_cast<intptr_t>(arena) | kMessageOwnedArenaTagMask
+ : reinterpret_cast<intptr_t>(arena);
+ GOOGLE_DCHECK(!is_message_owned || arena != nullptr);
+ }
+
+ // To keep the ABI identical between debug and non-debug builds,
+ // the destructor is always defined here even though it may delegate
+ // to a non-inline private method.
+ // (see https://github.com/protocolbuffers/protobuf/issues/9947)
+ ~InternalMetadata() {
+#if defined(NDEBUG) || defined(_MSC_VER)
+ if (HasMessageOwnedArenaTag()) {
+ delete reinterpret_cast<Arena*>(ptr_ - kMessageOwnedArenaTagMask);
+ }
+#else
+ CheckedDestruct();
+#endif
+ }
+
+ template <typename T>
+ void Delete() {
+ // Note that Delete<> should be called not more than once.
+ if (have_unknown_fields()) {
+ DeleteOutOfLineHelper<T>();
+ }
+ }
+
+ // DeleteReturnArena will delete the unknown fields only if they weren't
+ // allocated on an arena. Then it updates the flags so that if you call
+ // have_unknown_fields(), it will return false. Finally, it returns the
+ // current value of arena(). It is designed to be used as part of a
+ // Message class's destructor call, so that when control eventually gets
+ // to ~InternalMetadata(), we don't need to check for have_unknown_fields()
+ // again.
+ template <typename T>
+ Arena* DeleteReturnArena() {
+ if (have_unknown_fields()) {
+ return DeleteOutOfLineHelper<T>();
+ } else {
+ return PtrValue<Arena>();
+ }
+ }
+
+ PROTOBUF_NDEBUG_INLINE Arena* owning_arena() const {
+ return HasMessageOwnedArenaTag() ? nullptr : arena();
+ }
+
+ PROTOBUF_NDEBUG_INLINE Arena* user_arena() const {
+ Arena* a = arena();
+ return a && !a->IsMessageOwned() ? a : nullptr;
+ }
+
+ 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 Arena* DeleteOutOfLineHelper() {
+ if (auto* a = arena()) {
+ // Subtle: we want to preserve the message-owned arena flag, while at the
+ // same time replacing the pointer to Container<T> with a pointer to the
+ // arena.
+ intptr_t message_owned_arena_tag = ptr_ & kMessageOwnedArenaTagMask;
+ ptr_ = reinterpret_cast<intptr_t>(a) | message_owned_arena_tag;
+ return a;
+ } else {
+ delete PtrValue<Container<T>>();
+ ptr_ = 0;
+ return nullptr;
+ }
+ }
+
+ 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);
+ }
+
+ // Private helper with debug checks for ~InternalMetadata()
+ void CheckedDestruct();
+};
+
+// String Template specializations.
+
+template <>
+PROTOBUF_EXPORT void InternalMetadata::DoClear<std::string>();
+template <>
+PROTOBUF_EXPORT void InternalMetadata::DoMergeFrom<std::string>(
+ const std::string& other);
+template <>
+PROTOBUF_EXPORT void InternalMetadata::DoSwap<std::string>(std::string* 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<std::string>());
+ }
+ }
+ ~LiteUnknownFieldSetter() {
+ if (!buffer_.empty())
+ metadata_->mutable_unknown_fields<std::string>()->swap(buffer_);
+ }
+ std::string* buffer() { return &buffer_; }
+
+ private:
+ InternalMetadata* metadata_;
+ std::string buffer_;
+};
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_METADATA_LITE_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/package_info.h b/toolkit/components/protobuf/src/google/protobuf/package_info.h
new file mode 100644
index 0000000000..2b61679af5
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/package_info.h
@@ -0,0 +1,66 @@
+// 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 exists solely to document the google::protobuf namespace.
+// It is not compiled into anything, but it may be read by an automated
+// documentation generator.
+
+// Core components of the Protocol Buffers runtime library.
+//
+// The files in this package represent the core of the Protocol Buffer
+// system. All of them are part of the libprotobuf library.
+//
+// A note on thread-safety:
+//
+// Thread-safety in the Protocol Buffer library follows a simple rule:
+// unless explicitly noted otherwise, it is always safe to use an object
+// from multiple threads simultaneously as long as the object is declared
+// const in all threads (or, it is only used in ways that would be allowed
+// if it were declared const). However, if an object is accessed in one
+// thread in a way that would not be allowed if it were const, then it is
+// not safe to access that object in any other thread simultaneously.
+//
+// Put simply, read-only access to an object can happen in multiple threads
+// simultaneously, but write access can only happen in a single thread at
+// a time.
+//
+// The implementation does contain some "const" methods which actually modify
+// the object behind the scenes -- e.g., to cache results -- but in these cases
+// mutex locking is used to make the access thread-safe.
+namespace google {
+namespace protobuf {
+// TODO(gerbens) remove this comment, we need it to prevent clang-format
+// from combining the brackets. Which would mess with extract script
+} // namespace protobuf
+} // namespace google
diff --git a/toolkit/components/protobuf/src/google/protobuf/parse_context.cc b/toolkit/components/protobuf/src/google/protobuf/parse_context.cc
new file mode 100644
index 0000000000..59852fdb7f
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/parse_context.cc
@@ -0,0 +1,548 @@
+// 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/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/endian.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/wire_format_lite.h>
+
+// Must be included last.
+#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_GE(overrun, 0);
+ GOOGLE_DCHECK_LE(overrun, kSlopBytes);
+ auto ptr = begin + overrun;
+ auto end = begin + kSlopBytes;
+ while (ptr < end) {
+ uint32_t 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
+ uint64_t val;
+ ptr = VarintParse(ptr, &val);
+ if (ptr == nullptr) return false;
+ break;
+ }
+ case 1: { // fixed64
+ ptr += 8;
+ break;
+ }
+ case 2: { // len delim
+ int32_t 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_GT(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_GE(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_GT(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,
+ std::string* 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,
+ std::string* 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); });
+}
+
+
+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(uint64_t val, std::string* s) {
+ while (val >= 128) {
+ uint8_t c = val | 0x80;
+ s->push_back(c);
+ val >>= 7;
+ }
+ s->push_back(val);
+}
+
+void WriteVarint(uint32_t num, uint64_t val, std::string* s) {
+ WriteVarint(num << 3, s);
+ WriteVarint(val, s);
+}
+
+void WriteLengthDelimited(uint32_t num, StringPiece val, std::string* s) {
+ WriteVarint((num << 3) + 2, s);
+ WriteVarint(val.size(), s);
+ s->append(val.data(), val.size());
+}
+
+std::pair<const char*, uint32_t> VarintParseSlow32(const char* p,
+ uint32_t res) {
+ for (std::uint32_t i = 2; i < 5; i++) {
+ uint32_t 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 (std::uint32_t i = 5; i < 10; i++) {
+ uint32_t 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*, uint64_t> VarintParseSlow64(const char* p,
+ uint32_t res32) {
+ uint64_t res = res32;
+ for (std::uint32_t i = 2; i < 10; i++) {
+ uint64_t 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*, uint32_t> ReadTagFallback(const char* p, uint32_t res) {
+ for (std::uint32_t i = 2; i < 5; i++) {
+ uint32_t 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*, int32_t> ReadSizeFallback(const char* p, uint32_t res) {
+ for (std::uint32_t i = 1; i < 4; i++) {
+ uint32_t byte = static_cast<uint8_t>(p[i]);
+ res += (byte - 1) << (7 * i);
+ if (PROTOBUF_PREDICT_TRUE(byte < 128)) {
+ return {p + i + 1, res};
+ }
+ }
+ std::uint32_t 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<std::string*>(object);
+ str->append(begin, end - begin);
+ return end;
+}
+
+// Defined in wire_format_lite.cc
+void PrintUTF8ErrorLog(StringPiece message_name,
+ StringPiece 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(std::string* 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](uint64_t 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<int32_t, false>(object, ptr, ctx);
+}
+const char* PackedUInt32Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return VarintParser<uint32_t, false>(object, ptr, ctx);
+}
+const char* PackedInt64Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return VarintParser<int64_t, false>(object, ptr, ctx);
+}
+const char* PackedUInt64Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return VarintParser<uint64_t, false>(object, ptr, ctx);
+}
+const char* PackedSInt32Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return VarintParser<int32_t, true>(object, ptr, ctx);
+}
+const char* PackedSInt64Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return VarintParser<int64_t, 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<uint32_t>(object, ptr, ctx);
+}
+const char* PackedSFixed32Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return FixedParser<int32_t>(object, ptr, ctx);
+}
+const char* PackedFixed64Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return FixedParser<uint64_t>(object, ptr, ctx);
+}
+const char* PackedSFixed64Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return FixedParser<int64_t>(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(std::string* unknown)
+ : unknown_(unknown) {}
+
+ void AddVarint(uint32_t num, uint64_t value) {
+ if (unknown_ == nullptr) return;
+ WriteVarint(num * 8, unknown_);
+ WriteVarint(value, unknown_);
+ }
+ void AddFixed64(uint32_t num, uint64_t 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(uint32_t 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(uint32_t 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(uint32_t num, uint32_t 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:
+ std::string* unknown_;
+};
+
+const char* UnknownGroupLiteParse(std::string* unknown, const char* ptr,
+ ParseContext* ctx) {
+ UnknownFieldLiteParserHelper field_parser(unknown);
+ return WireFormatParser(field_parser, ptr, ctx);
+}
+
+const char* UnknownFieldParse(uint32_t tag, std::string* 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/toolkit/components/protobuf/src/google/protobuf/parse_context.h b/toolkit/components/protobuf/src/google/protobuf/parse_context.h
new file mode 100644
index 0000000000..7aea50cdc3
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/parse_context.h
@@ -0,0 +1,1025 @@
+// 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 <type_traits>
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/port.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/endian.h>
+#include <google/protobuf/implicit_weak_message.h>
+#include <google/protobuf/inlined_string_field.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>
+
+
+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(uint32_t num, uint64_t val, std::string* s);
+PROTOBUF_EXPORT void WriteLengthDelimited(uint32_t num, StringPiece val,
+ std::string* s);
+// Inline because it is just forwarding to s->WriteVarint
+inline void WriteVarint(uint32_t num, uint64_t val, UnknownFieldSet* s);
+inline void WriteLengthDelimited(uint32_t 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,
+ std::string* 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,
+ std::string* 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);
+
+ uint32_t LastTag() const { return last_tag_minus_1_ + 1; }
+ bool ConsumeEndGroup(uint32_t 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(uint32_t 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_);
+ }
+ bool AliasingEnabled() const { return aliasing_ != kNoAliasing; }
+ 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 {
+ 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.
+ uint32_t 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, std::string* str);
+ const char* ReadStringFallback(const char* ptr, int size, std::string* 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,
+ std::string* str) {
+ return AppendUntilEnd(
+ ptr, [str](const char* p, ptrdiff_t s) { str->append(p, s); });
+ }
+ friend class ImplicitWeakMessage;
+};
+
+using LazyEagerVerifyFnType = const char* (*)(const char* ptr,
+ ParseContext* ctx);
+using LazyEagerVerifyFnRef = std::remove_pointer<LazyEagerVerifyFnType>::type&;
+
+// 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);
+
+ // Spawns a child parsing context that inherits key properties. New context
+ // inherits the following:
+ // --depth_, data_, check_required_fields_, lazy_parse_mode_
+ // The spawned context always disables aliasing (different input).
+ template <typename... T>
+ ParseContext Spawn(const char** start, T&&... args) {
+ ParseContext spawned(depth_, false, start, std::forward<T>(args)...);
+ // Transfer key context states.
+ spawned.data_ = data_;
+ return spawned;
+ }
+
+ // 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, uint32_t 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 <uint32_t 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);
+ return little_endian::ToHost(tmp);
+ }
+};
+
+template <>
+struct EndianHelper<4> {
+ static uint32_t Load(const void* p) {
+ uint32_t tmp;
+ std::memcpy(&tmp, p, 4);
+ return little_endian::ToHost(tmp);
+ }
+};
+
+template <>
+struct EndianHelper<8> {
+ static uint64_t Load(const void* p) {
+ uint64_t tmp;
+ std::memcpy(&tmp, p, 8);
+ return little_endian::ToHost(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*, uint32_t> VarintParseSlow32(const char* p, uint32_t res);
+PROTOBUF_EXPORT
+std::pair<const char*, uint64_t> VarintParseSlow64(const char* p, uint32_t res);
+
+inline const char* VarintParseSlow(const char* p, uint32_t res, uint32_t* out) {
+ auto tmp = VarintParseSlow32(p, res);
+ *out = tmp.second;
+ return tmp.first;
+}
+
+inline const char* VarintParseSlow(const char* p, uint32_t res, uint64_t* 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);
+ uint32_t res = ptr[0];
+ if (!(res & 0x80)) {
+ *out = res;
+ return p + 1;
+ }
+ uint32_t 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*, uint32_t> ReadTagFallback(const char* p, uint32_t res);
+
+// Same as ParseVarint but only accept 5 bytes at most.
+inline const char* ReadTag(const char* p, uint32_t* out,
+ uint32_t /*max_tag*/ = 0) {
+ uint32_t res = static_cast<uint8_t>(p[0]);
+ if (res < 128) {
+ *out = res;
+ return p + 1;
+ }
+ uint32_t 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;
+}
+
+// As above, but optimized to consume very few registers while still being fast,
+// ReadTagInlined is useful for callers that don't mind the extra code but would
+// like to avoid an extern function call causing spills into the stack.
+//
+// Two support routines for ReadTagInlined come first...
+template <class T>
+PROTOBUF_NODISCARD PROTOBUF_ALWAYS_INLINE constexpr T RotateLeft(
+ T x, int s) noexcept {
+ return static_cast<T>(x << (s & (std::numeric_limits<T>::digits - 1))) |
+ static_cast<T>(x >> ((-s) & (std::numeric_limits<T>::digits - 1)));
+}
+
+PROTOBUF_NODISCARD inline PROTOBUF_ALWAYS_INLINE uint64_t
+RotRight7AndReplaceLowByte(uint64_t res, const char& byte) {
+#if defined(__x86_64__) && defined(__GNUC__)
+ // This will only use one register for `res`.
+ // `byte` comes as a reference to allow the compiler to generate code like:
+ //
+ // rorq $7, %rcx
+ // movb 1(%rax), %cl
+ //
+ // which avoids loading the incoming bytes into a separate register first.
+ asm("ror $7,%0\n\t"
+ "movb %1,%b0"
+ : "+r"(res)
+ : "m"(byte));
+#else
+ res = RotateLeft(res, -7);
+ res = res & ~0xFF;
+ res |= 0xFF & byte;
+#endif
+ return res;
+};
+
+inline PROTOBUF_ALWAYS_INLINE
+const char* ReadTagInlined(const char* ptr, uint32_t* out) {
+ uint64_t res = 0xFF & ptr[0];
+ if (PROTOBUF_PREDICT_FALSE(res >= 128)) {
+ res = RotRight7AndReplaceLowByte(res, ptr[1]);
+ if (PROTOBUF_PREDICT_FALSE(res & 0x80)) {
+ res = RotRight7AndReplaceLowByte(res, ptr[2]);
+ if (PROTOBUF_PREDICT_FALSE(res & 0x80)) {
+ res = RotRight7AndReplaceLowByte(res, ptr[3]);
+ if (PROTOBUF_PREDICT_FALSE(res & 0x80)) {
+ // Note: this wouldn't work if res were 32-bit,
+ // because then replacing the low byte would overwrite
+ // the bottom 4 bits of the result.
+ res = RotRight7AndReplaceLowByte(res, ptr[4]);
+ if (PROTOBUF_PREDICT_FALSE(res & 0x80)) {
+ // The proto format does not permit longer than 5-byte encodings for
+ // tags.
+ *out = 0;
+ return nullptr;
+ }
+ *out = static_cast<uint32_t>(RotateLeft(res, 28));
+#if defined(__GNUC__)
+ // Note: this asm statement prevents the compiler from
+ // trying to share the "return ptr + constant" among all
+ // branches.
+ asm("" : "+r"(ptr));
+#endif
+ return ptr + 5;
+ }
+ *out = static_cast<uint32_t>(RotateLeft(res, 21));
+ return ptr + 4;
+ }
+ *out = static_cast<uint32_t>(RotateLeft(res, 14));
+ return ptr + 3;
+ }
+ *out = static_cast<uint32_t>(RotateLeft(res, 7));
+ return ptr + 2;
+ }
+ *out = static_cast<uint32_t>(res);
+ return ptr + 1;
+}
+
+// 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
+// and edi, eax
+// add eax, edi
+// adc [rsi], 1
+inline uint32_t DecodeTwoBytes(const char** ptr) {
+ uint32_t value = UnalignedLoad<uint16_t>(*ptr);
+ // Sign extend the low byte continuation bit
+ uint32_t x = static_cast<int8_t>(value);
+ value &= x; // Mask out the high byte iff no continuation
+ // 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;
+}
+
+// More efficient varint parsing for big varints
+inline const char* ParseBigVarint(const char* p, uint64_t* out) {
+ auto pnew = p;
+ auto tmp = DecodeTwoBytes(&pnew);
+ uint64_t res = tmp >> 1;
+ if (PROTOBUF_PREDICT_TRUE(static_cast<std::int16_t>(tmp) >= 0)) {
+ *out = res;
+ return pnew;
+ }
+ for (std::uint32_t i = 1; i < 5; i++) {
+ pnew = p + 2 * i;
+ tmp = DecodeTwoBytes(&pnew);
+ res += (static_cast<std::uint64_t>(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*, int32_t> ReadSizeFallback(const char* p, uint32_t first);
+// Used for tags, could read up to 5 bytes which must be available. Additionally
+// it makes sure the unsigned value fits a int32_t, otherwise returns nullptr.
+// Caller must ensure its safe to call.
+inline uint32_t ReadSize(const char** pp) {
+ auto p = *pp;
+ uint32_t 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 uint64_t ReadVarint64(const char** p) {
+ uint64_t tmp;
+ *p = VarintParse(*p, &tmp);
+ return tmp;
+}
+
+inline uint32_t ReadVarint32(const char** p) {
+ uint32_t tmp;
+ *p = VarintParse(*p, &tmp);
+ return tmp;
+}
+
+inline int64_t ReadVarintZigZag64(const char** p) {
+ uint64_t tmp;
+ *p = VarintParse(*p, &tmp);
+ return WireFormatLite::ZigZagDecode64(tmp);
+}
+
+inline int32_t ReadVarintZigZag32(const char** p) {
+ uint64_t tmp;
+ *p = VarintParse(*p, &tmp);
+ return WireFormatLite::ZigZagDecode32(static_cast<uint32_t>(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) {
+ uint64_t 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 std::string* s, const char* field_name) {
+ return VerifyUTF8(*s, field_name);
+}
+
+// All the string parsers with or without UTF checking and for all CTypes.
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* InlineGreedyStringParser(
+ std::string* s, const char* ptr, ParseContext* ctx);
+
+
+template <typename T>
+PROTOBUF_NODISCARD const char* FieldParser(uint64_t tag, T& field_parser,
+ const char* ptr, ParseContext* ctx) {
+ uint32_t number = tag >> 3;
+ GOOGLE_PROTOBUF_PARSER_ASSERT(number != 0);
+ using WireType = internal::WireFormatLite::WireType;
+ switch (tag & 7) {
+ case WireType::WIRETYPE_VARINT: {
+ uint64_t value;
+ ptr = VarintParse(ptr, &value);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ field_parser.AddVarint(number, value);
+ break;
+ }
+ case WireType::WIRETYPE_FIXED64: {
+ uint64_t value = UnalignedLoad<uint64_t>(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: {
+ uint32_t value = UnalignedLoad<uint32_t>(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)) {
+ uint32_t 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_NODISCARD PROTOBUF_EXPORT const char* PackedInt32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedUInt32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedInt64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedUInt64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedSInt32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedSInt64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_NODISCARD PROTOBUF_EXPORT 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](uint64_t 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](uint64_t val) {
+ if (is_valid(data, val)) {
+ static_cast<RepeatedField<int>*>(object)->Add(val);
+ } else {
+ WriteVarint(field_num, val, metadata->mutable_unknown_fields<T>());
+ }
+ });
+}
+
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedBoolParser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedFixed32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedSFixed32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedFixed64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedSFixed64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedFloatParser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedDoubleParser(
+ void* object, const char* ptr, ParseContext* ctx);
+
+// This is the only recursive parser.
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* UnknownGroupLiteParse(
+ std::string* 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 std::string* vs
+// UnknownFieldSet* to make the generated code isomorphic between full and lite.
+PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* UnknownFieldParse(
+ uint32_t tag, std::string* 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/toolkit/components/protobuf/src/google/protobuf/port.h b/toolkit/components/protobuf/src/google/protobuf/port.h
new file mode 100644
index 0000000000..a5c060b6f6
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/port.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.
+
+// 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__
+
+#include <cstddef>
+#include <new>
+
+
+namespace google {
+namespace protobuf {
+namespace internal {
+inline void SizedDelete(void* p, size_t size) {
+#if defined(__cpp_sized_deallocation)
+ ::operator delete(p, size);
+#else
+ ::operator delete(p);
+#endif
+}
+inline void SizedArrayDelete(void* p, size_t size) {
+#if defined(__cpp_sized_deallocation)
+ ::operator delete[](p, size);
+#else
+ ::operator delete[](p);
+#endif
+}
+
+// Tag type used to invoke the constinit constructor overload of classes
+// such as ArenaStringPtr and MapFieldBase. Such constructors are internal
+// implementation details of the library.
+struct ConstantInitialized {
+ explicit ConstantInitialized() = default;
+};
+
+// Tag type used to invoke the arena constructor overload of classes such
+// as ExtensionSet and MapFieldLite in aggregate initialization. These
+// classes typically don't have move/copy constructors, which rules out
+// explicit initialization in pre-C++17.
+struct ArenaInitialized {
+ explicit ArenaInitialized() = default;
+};
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_PORT_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/port_def.inc b/toolkit/components/protobuf/src/google/protobuf/port_def.inc
new file mode 100644
index 0000000000..8943a4454f
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/port_def.inc
@@ -0,0 +1,928 @@
+// 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 PROTOBUF_BUILTIN_BSWAPxx definitions
+// Code must check for availability, e.g.: `defined(PROTOBUF_BUILTIN_BSWAP32)`
+#ifdef PROTOBUF_BUILTIN_BSWAP16
+#error PROTOBUF_BUILTIN_BSWAP16 was previously defined
+#endif
+#ifdef PROTOBUF_BUILTIN_BSWAP32
+#error PROTOBUF_BUILTIN_BSWAP32 was previously defined
+#endif
+#ifdef PROTOBUF_BUILTIN_BSWAP64
+#error PROTOBUF_BUILTIN_BSWAP64 was previously defined
+#endif
+#if defined(__GNUC__) || __has_builtin(__builtin_bswap16)
+#define PROTOBUF_BUILTIN_BSWAP16(x) __builtin_bswap16(x)
+#endif
+#if defined(__GNUC__) || __has_builtin(__builtin_bswap32)
+#define PROTOBUF_BUILTIN_BSWAP32(x) __builtin_bswap32(x)
+#endif
+#if defined(__GNUC__) || __has_builtin(__builtin_bswap64)
+#define PROTOBUF_BUILTIN_BSWAP64(x) __builtin_bswap64(x)
+#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.
+// PROTOBUF_FUTURE_FINAL is used on classes that are historically not marked as
+// final, but that may be marked final in future (breaking) releases.
+// #define PROTOBUF_FUTURE_BREAKING_CHANGES 1
+// #define PROTOBUF_FUTURE_FINAL final
+#define PROTOBUF_FUTURE_FINAL
+
+#ifdef PROTOBUF_VERSION
+#error PROTOBUF_VERSION was previously defined
+#endif
+#define PROTOBUF_VERSION 3021006
+
+#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 3021000
+
+#ifdef PROTOBUF_MIN_PROTOC_VERSION
+#error PROTOBUF_MIN_PROTOC_VERSION was previously defined
+#endif
+#define PROTOBUF_MIN_PROTOC_VERSION 3021000
+
+#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__) && \
+ !(defined(_MSC_VER) && defined(_M_IX86)) && \
+ !(defined(__NDK_MAJOR__) && __NDK_MAJOR <= 24)
+# ifndef PROTO2_OPENSOURCE
+// Compilation fails on ARM32: b/195943306
+// Compilation fails on powerpc64le: b/187985113
+// Compilation fails on X86 Windows:
+// https://github.com/llvm/llvm-project/issues/53271
+# 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
+#if __has_attribute(deprecated) || PROTOBUF_GNUC_MIN(3, 0)
+# define PROTOBUF_DEPRECATED __attribute__((deprecated))
+# define PROTOBUF_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
+#elif defined(_MSC_VER)
+# define PROTOBUF_DEPRECATED __declspec(deprecated)
+# define PROTOBUF_DEPRECATED_MSG(msg) __declspec(deprecated(msg))
+#else
+# define PROTOBUF_DEPRECATED
+# define PROTOBUF_DEPRECATED_MSG(msg)
+#endif
+
+#if defined(PROTOBUF_DEPRECATED_ENUM)
+#error PROTOBUF_DEPRECATED_ENUM was previously defined
+#endif
+#if defined(__clang__) || PROTOBUF_GNUC_MIN(6, 0)
+// https://gcc.gnu.org/gcc-6/changes.html
+# define PROTOBUF_DEPRECATED_ENUM __attribute__((deprecated))
+#else
+# define PROTOBUF_DEPRECATED_ENUM
+#endif
+
+#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 3021000
+
+#ifdef PROTOBUF_RTTI
+#error PROTOBUF_RTTI was previously defined
+#endif
+#if defined(GOOGLE_PROTOBUF_NO_RTTI) && GOOGLE_PROTOBUF_NO_RTTI
+// A user-provided definition GOOGLE_PROTOBUF_NO_RTTI=1 disables RTTI.
+#define PROTOBUF_RTTI 0
+#elif defined(__cpp_rtti)
+// https://en.cppreference.com/w/cpp/feature_test
+#define PROTOBUF_RTTI 1
+#elif __has_feature(cxx_rtti)
+// https://clang.llvm.org/docs/LanguageExtensions.html#c-rtti
+#define PROTOBUF_RTTI 1
+#elif defined(__GXX_RTTI)
+// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
+#define PROTOBUF_RTTI 1
+#elif defined(_CPPRTTI)
+// https://docs.microsoft.com/en-us/cpp/build/reference/gr-enable-run-time-type-information
+#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< ::uint32_t>(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(LIBPROTOC_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) && PROTOBUF_CPLUSPLUS_MIN(201703L)
+#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
+
+// Enable all stable experiments if this flag is set. This allows us to group
+// all of these experiments under a single build flag, which can be enabled in
+// the protobuf.stable-experiments TAP project.
+#ifdef PROTOBUF_ENABLE_STABLE_EXPERIMENTS
+#define PROTOBUF_FORCE_MESSAGE_OWNED_ARENA
+#endif // !PROTOBUF_ENABLE_STABLE_EXPERIMENTS
+
+#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
+
+#ifdef PROTOBUF_FORCE_RESET_IN_CLEAR
+#error PROTOBUF_FORCE_RESET_IN_CLEAR 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
+
+// TODO(b/228173843): cleanup PROTOBUF_LITTLE_ENDIAN in various 3p forks.
+#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
+ __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+#define PROTOBUF_LITTLE_ENDIAN 1
+#ifdef PROTOBUF_BIG_ENDIAN
+#error Conflicting PROTOBUF_BIG_ENDIAN was previously defined
+#endif
+#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
+ __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define PROTOBUF_BIG_ENDIAN 1
+#elif defined(_WIN32) || defined(__x86_64__) || defined(__aarch64__)
+#define PROTOBUF_LITTLE_ENDIAN 1
+#else
+#error "endian detection failed for current compiler"
+#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) && !defined(_MSC_VER)
+#define PROTOBUF_CONSTINIT constinit
+#define PROTOBUF_CONSTEXPR constexpr
+// Some older Clang versions incorrectly raise an error about
+// constant-initializing weak default instance pointers. Versions 12.0 and
+// higher seem to work, except that XCode 12.5.1 shows the error even though it
+// uses Clang 12.0.5.
+// Clang-cl on Windows raises error also.
+#elif !defined(_MSC_VER) && __has_cpp_attribute(clang::require_constant_initialization) && \
+ ((defined(__APPLE__) && __clang_major__ >= 13) || \
+ (!defined(__APPLE__) && __clang_major__ >= 12))
+#define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]]
+#define PROTOBUF_CONSTEXPR constexpr
+#elif PROTOBUF_GNUC_MIN(12, 2)
+#define PROTOBUF_CONSTINIT __constinit
+#define PROTOBUF_CONSTEXPR constexpr
+// MSVC 17 currently seems to raise an error about constant-initialized pointers.
+#elif defined(_MSC_VER) && _MSC_VER >= 1930
+#define PROTOBUF_CONSTINIT
+#define PROTOBUF_CONSTEXPR constexpr
+#else
+#define PROTOBUF_CONSTINIT
+#define PROTOBUF_CONSTEXPR
+#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
+
+// Force clang to always emit complete debug info for a type.
+// Clang uses constructor homing to determine when to emit debug info for a
+// type. If the constructor of a type is never used, which can happen in some
+// cases where member variables are constructed in place for optimization
+// purposes (see b/208803175 for an example), the type will have incomplete
+// debug info unless this attribute is used.
+#ifdef PROTOBUF_ATTRIBUTE_STANDALONE_DEBUG
+#error PROTOBUF_ATTRIBUTE_STANDALONE_DEBUG was previously defined
+#endif
+#if __has_cpp_attribute(clang::standalone_debug)
+#define PROTOBUF_ATTRIBUTE_STANDALONE_DEBUG [[clang::standalone_debug]]
+#else
+#define PROTOBUF_ATTRIBUTE_STANDALONE_DEBUG
+#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 for registration, to allow code that
+// really wants to higher priority to still beat us. Some initialization happens
+// at higher priority, though, since it is needed before registration.
+#ifdef PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
+#error PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 was previously defined
+#endif
+#ifdef PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
+#error PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 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_PRIORITY1 __attribute__((init_priority((101))))
+#define PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 __attribute__((init_priority((102))))
+#else
+#define PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
+#define PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
+#endif
+
+#ifdef PROTOBUF_PRAGMA_INIT_SEG
+#error PROTOBUF_PRAGMA_INIT_SEG was previously defined
+#endif
+#ifdef _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
+#endif
+
+#define PROTOBUF_TC_PARAM_DECL \
+ ::google::protobuf::MessageLite *msg, const char *ptr, \
+ ::google::protobuf::internal::ParseContext *ctx, \
+ const ::google::protobuf::internal::TcParseTableBase *table, \
+ uint64_t 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
+
+// ThreadSafeArenaz is turned off completely in opensource builds.
+
+// 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("GetClassName")
+#undef GetClassName
+#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("STATUS_PENDING")
+#undef STATUS_PENDING
+#pragma push_macro("STRICT")
+#undef STRICT
+#pragma push_macro("timezone")
+#undef timezone
+#endif // _MSC_VER
+
+#ifdef __APPLE__
+// Inconvenient macro names from usr/include/math.h in some macOS SDKs.
+#pragma push_macro("DOMAIN")
+#undef DOMAIN
+// Inconvenient macro names from /usr/include/mach/boolean.h in some macOS SDKs.
+#pragma push_macro("TRUE")
+#undef TRUE
+#pragma push_macro("FALSE")
+#undef FALSE
+// Inconvenient macro names from usr/include/sys/syslimits.h in some macOS SDKs.
+#pragma push_macro("UID_MAX")
+#undef UID_MAX
+#endif // __APPLE__
+
+#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 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.
+#ifdef _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
diff --git a/toolkit/components/protobuf/src/google/protobuf/port_undef.inc b/toolkit/components/protobuf/src/google/protobuf/port_undef.inc
new file mode 100644
index 0000000000..e880fa5c59
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/port_undef.inc
@@ -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.
+
+// #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_BUILTIN_BSWAP16
+#undef PROTOBUF_BUILTIN_BSWAP32
+#undef PROTOBUF_BUILTIN_BSWAP64
+#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_RESET_IN_CLEAR
+#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_FUTURE_FINAL
+#undef PROTOBUF_THREAD_LOCAL
+#undef PROTOBUF_LITTLE_ENDIAN
+#undef PROTOBUF_BIG_ENDIAN
+#undef PROTOBUF_MESSAGE_OWNED_ARENA_EXPERIMENT
+#undef PROTOBUF_CONSTINIT
+#undef PROTOBUF_CONSTEXPR
+#undef PROTOBUF_ATTRIBUTE_WEAK
+#undef PROTOBUF_HAVE_ATTRIBUTE_WEAK
+#undef PROTOBUF_ATTRIBUTE_NO_DESTROY
+#undef PROTOBUF_ATTRIBUTE_STANDALONE_DEBUG
+#undef PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
+#undef PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
+#undef PROTOBUF_PRAGMA_INIT_SEG
+#undef PROTOBUF_ASAN
+#undef PROTOBUF_MSAN
+#undef PROTOBUF_TSAN
+#undef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED
+#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("GetClassName")
+#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("STATUS_PENDING")
+#pragma pop_macro("timezone")
+#endif
+
+#ifdef __APPLE__
+#pragma pop_macro("DOMAIN")
+#pragma pop_macro("TRUE")
+#pragma pop_macro("FALSE")
+#pragma pop_macro("UID_MAX")
+#endif // __APPLE__
+
+#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
+#pragma pop_macro("DEBUG")
+#endif // defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+// Pop the warning(push) from port_def.inc
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
diff --git a/toolkit/components/protobuf/src/google/protobuf/reflection.h b/toolkit/components/protobuf/src/google/protobuf/reflection.h
new file mode 100644
index 0000000000..7b75a43f22
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/reflection.h
@@ -0,0 +1,570 @@
+// 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
+
+// Must be included last.
+#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 int32_t int32_t
+// CPPTYPE_UINT32 uint32_t uint32_t
+// CPPTYPE_INT64 int64_t int64_t
+// CPPTYPE_UINT64 uint64_t uint64_t
+// CPPTYPE_DOUBLE double double
+// CPPTYPE_FLOAT float float
+// CPPTYPE_BOOL bool bool
+// CPPTYPE_ENUM generated enum type int32_t
+// CPPTYPE_STRING string std::string
+// CPPTYPE_MESSAGE generated message type google::protobuf::Message
+// or google::protobuf::Message
+//
+// Note that for enums we use int32_t 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 int32_t). 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 int32_t). 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, int32_t)
+DEFINE_PRIMITIVE(UINT32, uint32_t)
+DEFINE_PRIMITIVE(INT64, int64_t)
+DEFINE_PRIMITIVE(UINT64, uint64_t)
+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 int32_t for repeated enums in RepeatedFieldAccessor.
+ typedef int32_t AccessorValueType;
+ typedef T IteratorValueType;
+ typedef int32_t* 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<std::string, T>::value>::type> {
+ typedef RepeatedFieldRefIterator<T> iterator;
+ typedef RepeatedFieldAccessor AccessorType;
+ typedef std::string AccessorValueType;
+ typedef const std::string IteratorValueType;
+ typedef const std::string* 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/toolkit/components/protobuf/src/google/protobuf/reflection_internal.h b/toolkit/components/protobuf/src/google/protobuf/reflection_internal.h
new file mode 100644
index 0000000000..f749c3eb11
--- /dev/null
+++ b/toolkit/components/protobuf/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<std::string> {
+ 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<std::string> tmp;
+ tmp.Swap(MutableRepeatedField(data));
+ int other_size = other_mutator->Size(other_data);
+ for (int i = 0; i < other_size; ++i) {
+ Add<std::string>(data, other_mutator->Get<std::string>(other_data, i));
+ }
+ int size = Size(data);
+ other_mutator->Clear(other_data);
+ for (int i = 0; i < size; ++i) {
+ other_mutator->Add<std::string>(other_data, tmp.Get(i));
+ }
+ }
+ }
+
+ protected:
+ std::string* New(const Value*) const override { return new std::string(); }
+ void ConvertToT(const Value* value, std::string* result) const override {
+ *result = *static_cast<const std::string*>(value);
+ }
+ const Value* ConvertFromT(const std::string& 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/toolkit/components/protobuf/src/google/protobuf/reflection_ops.cc b/toolkit/components/protobuf/src/google/protobuf/reflection_ops.cc
new file mode 100644
index 0000000000..3a1972e274
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/reflection_ops.cc
@@ -0,0 +1,459 @@
+// 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.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/map_field.h>
+#include <google/protobuf/map_field_inl.h>
+#include <google/protobuf/unknown_field_set.h>
+
+// Must be included last.
+#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 std::string& 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;
+ }
+ }
+ }
+
+ if (!from_reflection->GetUnknownFields(from).empty()) {
+ 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);
+ }
+
+ if (reflection->GetInternalMetadata(*message).have_unknown_fields()) {
+ 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 std::string SubMessagePrefix(const std::string& prefix,
+ const FieldDescriptor* field, int index) {
+ std::string 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 std::string& prefix,
+ std::vector<std::string>* 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::InternalGetOwningArena(lhs) !=
+ Arena::InternalGetOwningArena(rhs));
+ GOOGLE_DCHECK(Arena::InternalGetOwningArena(lhs) != nullptr ||
+ Arena::InternalGetOwningArena(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::InternalGetOwningArena(rhs);
+ if (arena == nullptr) {
+ std::swap(lhs, rhs);
+ arena = Arena::InternalGetOwningArena(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/toolkit/components/protobuf/src/google/protobuf/reflection_ops.h b/toolkit/components/protobuf/src/google/protobuf/reflection_ops.h
new file mode 100644
index 0000000000..0a45702f9b
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/reflection_ops.h
@@ -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.
+
+// 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
+
+// Must be included last.
+#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 std::string& prefix,
+ std::vector<std::string>* 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/toolkit/components/protobuf/src/google/protobuf/repeated_field.cc b/toolkit/components/protobuf/src/google/protobuf/repeated_field.cc
new file mode 100644
index 0000000000..7264d0a1e3
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/repeated_field.cc
@@ -0,0 +1,71 @@
+// 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>
+
+// Must be included last.
+#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<int32_t>;
+template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<uint32_t>;
+template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<int64_t>;
+template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<uint64_t>;
+template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<float>;
+template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<double>;
+template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedPtrField<std::string>;
+
+namespace internal {
+template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedIterator<bool>;
+template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedIterator<int32_t>;
+template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedIterator<uint32_t>;
+template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedIterator<int64_t>;
+template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedIterator<uint64_t>;
+template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedIterator<float>;
+template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedIterator<double>;
+} // namespace internal
+
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
diff --git a/toolkit/components/protobuf/src/google/protobuf/repeated_field.h b/toolkit/components/protobuf/src/google/protobuf/repeated_field.h
new file mode 100644
index 0000000000..3fb734e5cb
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/repeated_field.h
@@ -0,0 +1,1219 @@
+// 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.
+//
+// This header covers RepeatedField.
+
+#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
+#define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
+
+
+#include <algorithm>
+#include <iterator>
+#include <limits>
+#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/message_lite.h>
+#include <google/protobuf/repeated_ptr_field.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 {
+
+template <typename T, int kRepHeaderSize>
+constexpr int RepeatedFieldLowerClampLimit() {
+ // The header is padded to be at least `sizeof(T)` when it would be smaller
+ // otherwise.
+ static_assert(sizeof(T) <= kRepHeaderSize, "");
+ // We want to pad the minimum size to be a power of two bytes, including the
+ // header.
+ // The first allocation is kRepHeaderSize bytes worth of elements for a total
+ // of 2*kRepHeaderSize bytes.
+ // For an 8-byte header, we allocate 8 bool, 2 ints, or 1 int64.
+ return kRepHeaderSize / sizeof(T);
+}
+
+// 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(uint32_t, 8)
+
+#ifdef __SIZEOF_INT128__
+PROTO_MEMSWAP_DEF_SIZE(uint64_t, 16)
+PROTO_MEMSWAP_DEF_SIZE(__uint128_t, (1u << 31))
+#else
+PROTO_MEMSWAP_DEF_SIZE(uint64_t, (1u << 31))
+#endif
+
+#undef PROTO_MEMSWAP_DEF_SIZE
+
+template <typename Element>
+class RepeatedIterator;
+
+} // 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 final {
+ 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 returns a pointer to it.
+ // The new element is uninitialized if |Element| is a POD type.
+ Element* Add();
+ // Appends elements in the range [begin, end) after reserving
+ // the appropriate number of elements.
+ template <typename Iter>
+ void Add(Iter begin, Iter end);
+
+ // Removes the last element in the array.
+ void RemoveLast();
+
+ // Extracts elements with indices in "[start .. start+num-1]".
+ // Copies them into "elements[0 .. num-1]" if "elements" is not nullptr.
+ // Caution: 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);
+
+ // Reserves 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);
+
+ // Resizes 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;
+
+ // Swaps entire contents with "other". If they are separate arenas then,
+ // copies data between each other.
+ void Swap(RepeatedField* other);
+
+ // Swaps 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);
+
+ // Swaps two elements.
+ void SwapElements(int index1, int index2);
+
+ // STL-like iterator support
+ typedef internal::RepeatedIterator<Element> iterator;
+ typedef internal::RepeatedIterator<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);
+
+ // Gets the Arena on which this RepeatedField stores its elements.
+ inline Arena* GetArena() const {
+ return GetOwningArena();
+ }
+
+ // For internal use only.
+ //
+ // This is public due to it being called by generated code.
+ inline void InternalSwap(RepeatedField* other);
+
+ private:
+ template <typename T> friend class Arena::InternalHelper;
+
+ // Gets the Arena on which this RepeatedField stores its elements.
+ inline Arena* GetOwningArena() const {
+ return (total_size_ == 0) ? static_cast<Arena*>(arena_or_elements_)
+ : rep()->arena;
+ }
+
+ 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_;
+ // Pad the Rep after arena allow for power-of-two byte sizes when
+ // sizeof(Element) > sizeof(Arena*). eg for 16-byte objects.
+ static PROTOBUF_CONSTEXPR const size_t kRepHeaderSize =
+ sizeof(Arena*) < sizeof(Element) ? sizeof(Element) : sizeof(Arena*);
+ struct Rep {
+ Arena* arena;
+ Element* elements() {
+ return reinterpret_cast<Element*>(reinterpret_cast<char*>(this) +
+ kRepHeaderSize);
+ }
+ };
+
+ // 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_;
+
+ // Returns a 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();
+ }
+
+ // Returns a pointer to elements array if it exists; otherwise either null or
+ // an 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_);
+ }
+
+ // Returns a pointer to the Rep struct.
+ // pre-condition: the Rep must have been allocated, ie elements() is safe.
+ Rep* rep() const {
+ return reinterpret_cast<Rep*>(reinterpret_cast<char*>(elements()) -
+ kRepHeaderSize);
+ }
+
+ friend class Arena;
+ typedef void InternalArenaConstructable_;
+
+ // Moves 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);
+
+ // Copies 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, bool in_destructor) {
+ 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();
+ }
+ }
+ const size_t bytes = size * sizeof(*e) + kRepHeaderSize;
+ if (rep->arena == nullptr) {
+ internal::SizedDelete(rep, bytes);
+ } else if (!in_destructor) {
+ // If we are in the destructor, we might be being destroyed as part of
+ // the arena teardown. We can't try and return blocks to the arena then.
+ rep->arena->ReturnArrayMemory(rep, bytes);
+ }
+ }
+ }
+
+ // 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 its
+ // 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 that 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 executes at only 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 = GetOwningArena();
+ if (arena) (void)arena->SpaceAllocated();
+#endif
+ if (total_size_ > 0) {
+ InternalDeallocate(rep(), total_size_, true);
+ }
+}
+
+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.GetOwningArena()) {
+ 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 (GetOwningArena() != other.GetOwningArena()
+#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ || GetOwningArena() == 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 elements) {
+ GOOGLE_DCHECK_GE(total_size_ - current_size_, elements)
+ << total_size_ << ", " << current_size_;
+ // Warning: sometimes people call this when elements == 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_ += elements;
+ 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) {
+ uint32_t 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() {
+ uint32_t 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 (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+#else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ RepeatedField<Element> temp(other->GetOwningArena());
+ temp.MergeFrom(*this);
+ CopyFrom(*other);
+ other->UnsafeArenaSwap(&temp);
+ }
+}
+
+template <typename Element>
+void RepeatedField<Element>::UnsafeArenaSwap(RepeatedField* other) {
+ if (this == other) return;
+ GOOGLE_DCHECK_EQ(GetOwningArena(), other->GetOwningArena());
+ 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 iterator(unsafe_elements());
+}
+template <typename Element>
+inline typename RepeatedField<Element>::const_iterator
+RepeatedField<Element>::begin() const {
+ return const_iterator(unsafe_elements());
+}
+template <typename Element>
+inline typename RepeatedField<Element>::const_iterator
+RepeatedField<Element>::cbegin() const {
+ return const_iterator(unsafe_elements());
+}
+template <typename Element>
+inline typename RepeatedField<Element>::iterator RepeatedField<Element>::end() {
+ return iterator(unsafe_elements() + current_size_);
+}
+template <typename Element>
+inline typename RepeatedField<Element>::const_iterator
+RepeatedField<Element>::end() const {
+ return const_iterator(unsafe_elements() + current_size_);
+}
+template <typename Element>
+inline typename RepeatedField<Element>::const_iterator
+RepeatedField<Element>::cend() const {
+ return const_iterator(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)
+template <typename T, int kRepHeaderSize>
+inline int CalculateReserveSize(int total_size, int new_size) {
+ constexpr int lower_limit = RepeatedFieldLowerClampLimit<T, kRepHeaderSize>();
+ if (new_size < lower_limit) {
+ // Clamp to smallest allowed size.
+ return lower_limit;
+ }
+ constexpr int kMaxSizeBeforeClamp =
+ (std::numeric_limits<int>::max() - kRepHeaderSize) / 2;
+ if (PROTOBUF_PREDICT_FALSE(total_size > kMaxSizeBeforeClamp)) {
+ return std::numeric_limits<int>::max();
+ }
+ // We want to double the number of bytes, not the number of elements, to try
+ // to stay within power-of-two allocations.
+ // The allocation has kRepHeaderSize + sizeof(T) * capacity.
+ int doubled_size = 2 * total_size + kRepHeaderSize / sizeof(T);
+ return std::max(doubled_size, new_size);
+}
+} // 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 = GetOwningArena();
+
+ new_size = internal::CalculateReserveSize<Element, kRepHeaderSize>(
+ 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., int32_t), 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, false);
+
+}
+
+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 {
+
+// STL-like iterator implementation for RepeatedField. You should not
+// refer to this class directly; use RepeatedField<T>::iterator instead.
+//
+// Note: All of the iterator operators *must* be inlined to avoid performance
+// regressions. This is caused by the extern template declarations below (which
+// are required because of the RepeatedField extern template declarations). If
+// any of these functions aren't explicitly inlined (e.g. defined in the class),
+// the compiler isn't allowed to inline them.
+template <typename Element>
+class RepeatedIterator {
+ public:
+ using iterator_category = std::random_access_iterator_tag;
+ // Note: remove_const is necessary for std::partial_sum, which uses value_type
+ // to determine the summation variable type.
+ using value_type = typename std::remove_const<Element>::type;
+ using difference_type = std::ptrdiff_t;
+ using pointer = Element*;
+ using reference = Element&;
+
+ constexpr RepeatedIterator() noexcept : it_(nullptr) {}
+
+ // Allows "upcasting" from RepeatedIterator<T**> to
+ // RepeatedIterator<const T*const*>.
+ template <typename OtherElement,
+ typename std::enable_if<std::is_convertible<
+ OtherElement*, pointer>::value>::type* = nullptr>
+ constexpr RepeatedIterator(
+ const RepeatedIterator<OtherElement>& other) noexcept
+ : it_(other.it_) {}
+
+ // dereferenceable
+ constexpr reference operator*() const noexcept { return *it_; }
+ constexpr pointer operator->() const noexcept { return it_; }
+
+ private:
+ // Helper alias to hide the internal type.
+ using iterator = RepeatedIterator<Element>;
+
+ public:
+ // {inc,dec}rementable
+ iterator& operator++() noexcept {
+ ++it_;
+ return *this;
+ }
+ iterator operator++(int) noexcept { return iterator(it_++); }
+ iterator& operator--() noexcept {
+ --it_;
+ return *this;
+ }
+ iterator operator--(int) noexcept { return iterator(it_--); }
+
+ // equality_comparable
+ friend constexpr bool operator==(const iterator& x,
+ const iterator& y) noexcept {
+ return x.it_ == y.it_;
+ }
+ friend constexpr bool operator!=(const iterator& x,
+ const iterator& y) noexcept {
+ return x.it_ != y.it_;
+ }
+
+ // less_than_comparable
+ friend constexpr bool operator<(const iterator& x,
+ const iterator& y) noexcept {
+ return x.it_ < y.it_;
+ }
+ friend constexpr bool operator<=(const iterator& x,
+ const iterator& y) noexcept {
+ return x.it_ <= y.it_;
+ }
+ friend constexpr bool operator>(const iterator& x,
+ const iterator& y) noexcept {
+ return x.it_ > y.it_;
+ }
+ friend constexpr bool operator>=(const iterator& x,
+ const iterator& y) noexcept {
+ return x.it_ >= y.it_;
+ }
+
+ // addable, subtractable
+ iterator& operator+=(difference_type d) noexcept {
+ it_ += d;
+ return *this;
+ }
+ constexpr iterator operator+(difference_type d) const noexcept {
+ return iterator(it_ + d);
+ }
+ friend constexpr iterator operator+(const difference_type d,
+ iterator it) noexcept {
+ return it + d;
+ }
+
+ iterator& operator-=(difference_type d) noexcept {
+ it_ -= d;
+ return *this;
+ }
+ iterator constexpr operator-(difference_type d) const noexcept {
+ return iterator(it_ - d);
+ }
+
+ // indexable
+ constexpr reference operator[](difference_type d) const noexcept {
+ return it_[d];
+ }
+
+ // random access iterator
+ friend constexpr difference_type operator-(iterator it1,
+ iterator it2) noexcept {
+ return it1.it_ - it2.it_;
+ }
+
+ private:
+ template <typename OtherElement>
+ friend class RepeatedIterator;
+
+ // Allow construction from RepeatedField.
+ friend class RepeatedField<value_type>;
+ explicit RepeatedIterator(Element* it) noexcept : it_(it) {}
+
+ // The internal iterator.
+ Element* it_;
+};
+
+// 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<int32_t>;
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<uint32_t>;
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<int64_t>;
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<uint64_t>;
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<float>;
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<double>;
+
+namespace internal {
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedIterator<bool>;
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE
+ RepeatedIterator<int32_t>;
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE
+ RepeatedIterator<uint32_t>;
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE
+ RepeatedIterator<int64_t>;
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE
+ RepeatedIterator<uint64_t>;
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedIterator<float>;
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedIterator<double>;
+} // namespace internal
+
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/repeated_ptr_field.cc b/toolkit/components/protobuf/src/google/protobuf/repeated_ptr_field.cc
new file mode 100644
index 0000000000..8e86727144
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/repeated_ptr_field.cc
@@ -0,0 +1,152 @@
+// 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 <algorithm>
+
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/implicit_weak_message.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/port.h>
+
+// Must be included last.
+#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 = GetOwningArena();
+ new_size = internal::CalculateReserveSize<void*, kRepHeaderSize>(total_size_,
+ new_size);
+ GOOGLE_CHECK_LE(static_cast<int64_t>(new_size),
+ static_cast<int64_t>(
+ (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));
+ }
+ const int old_total_size = total_size_;
+ total_size_ = new_size;
+ if (old_rep) {
+ if (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;
+
+ const size_t old_size =
+ old_total_size * sizeof(rep_->elements[0]) + kRepHeaderSize;
+ if (arena == nullptr) {
+ internal::SizedDelete(old_rep, old_size);
+ } else {
+ arena_->ReturnArrayMemory(old_rep, old_size);
+ }
+ } else {
+ rep_->allocated_size = 0;
+ }
+ 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]);
+ }
+ const size_t size = total_size_ * sizeof(elements[0]) + kRepHeaderSize;
+ internal::SizedDelete(rep_, size);
+ rep_ = nullptr;
+}
+
+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/toolkit/components/protobuf/src/google/protobuf/repeated_ptr_field.h b/toolkit/components/protobuf/src/google/protobuf/repeated_ptr_field.h
new file mode 100644
index 0000000000..401230bf51
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/repeated_ptr_field.h
@@ -0,0 +1,1970 @@
+// 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.
+//
+// This header covers RepeatedPtrField.
+
+// IWYU pragma: private, include "net/proto2/public/repeated_field.h"
+
+#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/port.h>
+#include <google/protobuf/message_lite.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 std::string*.
+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<std::string> {
+ 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()
+ : arena_(nullptr), current_size_(0), total_size_(0), rep_(nullptr) {}
+ explicit RepeatedPtrFieldBase(Arena* arena)
+ : arena_(arena), current_size_(0), total_size_(0), rep_(nullptr) {}
+
+ RepeatedPtrFieldBase(const RepeatedPtrFieldBase&) = delete;
+ RepeatedPtrFieldBase& operator=(const RepeatedPtrFieldBase&) = delete;
+
+ ~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
+ }
+
+ bool empty() const { return current_size_ == 0; }
+ int size() const { return current_size_; }
+ int Capacity() const { return total_size_; }
+
+ template <typename TypeHandler>
+ const typename TypeHandler::Type& at(int index) const {
+ GOOGLE_CHECK_GE(index, 0);
+ GOOGLE_CHECK_LT(index, current_size_);
+ return *cast<TypeHandler>(rep_->elements[index]);
+ }
+
+ template <typename TypeHandler>
+ typename TypeHandler::Type& at(int index) {
+ GOOGLE_CHECK_GE(index, 0);
+ GOOGLE_CHECK_LT(index, current_size_);
+ return *cast<TypeHandler>(rep_->elements[index]);
+ }
+
+ template <typename TypeHandler>
+ typename TypeHandler::Type* Mutable(int index) {
+ GOOGLE_DCHECK_GE(index, 0);
+ GOOGLE_DCHECK_LT(index, current_size_);
+ return cast<TypeHandler>(rep_->elements[index]);
+ }
+
+ template <typename TypeHandler>
+ typename TypeHandler::Type* Add(
+ const typename TypeHandler::Type* prototype = nullptr) {
+ 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* = nullptr>
+ inline void 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>
+ void Delete(int index) {
+ GOOGLE_DCHECK_GE(index, 0);
+ GOOGLE_DCHECK_LT(index, current_size_);
+ TypeHandler::Delete(cast<TypeHandler>(rep_->elements[index]), arena_);
+ }
+
+ // Must be called from destructor.
+ template <typename TypeHandler>
+ void 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);
+ }
+ const size_t size = total_size_ * sizeof(elements[0]) + kRepHeaderSize;
+ internal::SizedDelete(rep_, size);
+ }
+ rep_ = nullptr;
+ }
+
+ bool NeedsDestroy() const { return rep_ != nullptr && arena_ == nullptr; }
+ void DestroyProtos(); // implemented in the cc file
+
+ 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 {
+ GOOGLE_DCHECK_GE(index, 0);
+ GOOGLE_DCHECK_LT(index, current_size_);
+ return *cast<TypeHandler>(rep_->elements[index]);
+ }
+
+ // 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() {
+ 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;
+ }
+ }
+
+ template <typename TypeHandler>
+ void MergeFrom(const RepeatedPtrFieldBase& other) {
+ // 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.
+ GOOGLE_DCHECK_NE(&other, this);
+ if (other.current_size_ == 0) return;
+ MergeFromInternal(other,
+ &RepeatedPtrFieldBase::MergeFromInnerLoop<TypeHandler>);
+ }
+
+ inline void 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;
+ }
+
+ protected:
+ template <typename TypeHandler>
+ void RemoveLast() {
+ GOOGLE_DCHECK_GT(current_size_, 0);
+ TypeHandler::Clear(cast<TypeHandler>(rep_->elements[--current_size_]));
+ }
+
+ template <typename TypeHandler>
+ void CopyFrom(const RepeatedPtrFieldBase& other) {
+ if (&other == this) return;
+ RepeatedPtrFieldBase::Clear<TypeHandler>();
+ RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
+ }
+
+ void CloseGap(int start, int num); // implemented in the cc file
+
+ void Reserve(int new_size); // implemented in the cc file
+
+ 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 { return rep_ ? rep_->elements : nullptr; }
+ void** raw_mutable_data() const {
+ return rep_ ? const_cast<void**>(rep_->elements) : nullptr;
+ }
+
+ template <typename TypeHandler>
+ typename TypeHandler::Type** 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>
+ const typename TypeHandler::Type* const* 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());
+ }
+
+ template <typename TypeHandler>
+ PROTOBUF_NDEBUG_INLINE void Swap(RepeatedPtrFieldBase* other) {
+#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 {
+ SwapFallback<TypeHandler>(other);
+ }
+ }
+
+ void SwapElements(int index1, int index2) {
+ using std::swap; // enable ADL with fallback
+ swap(rep_->elements[index1], rep_->elements[index2]);
+ }
+
+ template <typename TypeHandler>
+ size_t 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;
+ }
+
+ // Advanced memory management --------------------------------------
+
+ // Like Add(), but if there are no cleared objects to use, returns nullptr.
+ template <typename TypeHandler>
+ typename TypeHandler::Type* AddFromCleared() {
+ if (rep_ != nullptr && current_size_ < rep_->allocated_size) {
+ return cast<TypeHandler>(rep_->elements[current_size_++]);
+ } else {
+ return nullptr;
+ }
+ }
+
+ 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) {
+ // 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;
+ }
+
+ template <typename TypeHandler>
+ PROTOBUF_NODISCARD typename TypeHandler::Type* ReleaseLast() {
+ typename TypeImplementsMergeBehavior<typename TypeHandler::Type>::type t;
+ return ReleaseLastInternal<TypeHandler>(t);
+ }
+
+ // Releases and returns the last element, but does not do out-of-arena copy.
+ // Instead, just returns the raw pointer to the contained element in the
+ // arena.
+ template <typename TypeHandler>
+ typename TypeHandler::Type* 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;
+ }
+
+ int ClearedCount() const {
+ return rep_ ? (rep_->allocated_size - current_size_) : 0;
+ }
+
+ template <typename TypeHandler>
+ void AddCleared(typename TypeHandler::Type* value) {
+ GOOGLE_DCHECK(GetOwningArena() == 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>
+ PROTOBUF_NODISCARD typename TypeHandler::Type* ReleaseCleared() {
+ GOOGLE_DCHECK(GetOwningArena() == nullptr)
+ << "ReleaseCleared() can only be used on a RepeatedPtrField not on "
+ << "an arena.";
+ GOOGLE_DCHECK(GetOwningArena() == nullptr);
+ GOOGLE_DCHECK(rep_ != nullptr);
+ GOOGLE_DCHECK_GT(rep_->allocated_size, current_size_);
+ return cast<TypeHandler>(rep_->elements[--rep_->allocated_size]);
+ }
+
+ template <typename TypeHandler>
+ void AddAllocatedInternal(typename TypeHandler::Type* value, std::true_type) {
+ // AddAllocated version that implements arena-safe copying behavior.
+ Arena* element_arena =
+ reinterpret_cast<Arena*>(TypeHandler::GetOwningArena(value));
+ Arena* arena = GetOwningArena();
+ 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);
+ }
+ }
+
+ template <typename TypeHandler>
+ void AddAllocatedInternal(
+ // AddAllocated version that does not implement arena-safe copying
+ // behavior.
+ 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);
+ }
+ }
+
+ // Slowpath handles all cases, copying if necessary.
+ template <typename TypeHandler>
+ PROTOBUF_NOINLINE void 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);
+ }
+
+ template <typename TypeHandler>
+ typename TypeHandler::Type* ReleaseLastInternal(std::true_type) {
+ // ReleaseLast() for types that implement merge/copy behavior.
+ // First, release an element.
+ typename TypeHandler::Type* result = UnsafeArenaReleaseLast<TypeHandler>();
+ // Now perform a copy if we're on an arena.
+ Arena* arena = GetOwningArena();
+
+ 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;
+ }
+
+ template <typename TypeHandler>
+ typename TypeHandler::Type* ReleaseLastInternal(std::false_type) {
+ // 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.
+ GOOGLE_DCHECK(GetOwningArena() == 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>
+ PROTOBUF_NOINLINE void SwapFallback(RepeatedPtrFieldBase* other) {
+#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ GOOGLE_DCHECK(GetOwningArena() == nullptr ||
+ other->GetOwningArena() != GetOwningArena());
+#else // PROTOBUF_FORCE_COPY_IN_SWAP
+ GOOGLE_DCHECK(other->GetOwningArena() != GetOwningArena());
+#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->GetOwningArena());
+ 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 Arena* GetArena() const { return arena_; }
+
+ protected:
+ inline Arena* GetOwningArena() const { return arena_; }
+
+ private:
+ template <typename T> friend class Arena::InternalHelper;
+
+ 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 would cost
+ // 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)) {
+ // 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>
+ PROTOBUF_NOINLINE void MergeFromInnerLoop(void** our_elems,
+ void** other_elems, int length,
+ int already_allocated) {
+ if (already_allocated < length) {
+ Arena* arena = GetOwningArena();
+ 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);
+ }
+ }
+
+ // Internal helper: extends array space if necessary to contain
+ // |extend_amount| more elements, and returns 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: adds "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;
+ friend class internal::TcParser; // TODO(jorg): Remove this friend.
+};
+
+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) {
+ return New(arena);
+ }
+ 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(); }
+ static void Merge(const GenericType& from, GenericType* to);
+ static inline size_t SpaceUsedLong(const GenericType& value) {
+ return value.SpaceUsedLong();
+ }
+};
+
+// NewFromPrototypeHelper() is not defined inline here, as we will need to do a
+// virtual function dispatch anyways to go from Message* to call New/Merge. (The
+// additional helper is needed as a workaround for MSVC.)
+MessageLite* NewFromPrototypeHelper(const MessageLite* prototype, Arena* arena);
+
+template <>
+inline MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
+ const MessageLite* prototype, Arena* arena) {
+ return NewFromPrototypeHelper(prototype, arena);
+}
+template <>
+inline Arena* GenericTypeHandler<MessageLite>::GetOwningArena(
+ MessageLite* value) {
+ return value->GetOwningArena();
+}
+
+template <typename GenericType>
+PROTOBUF_NOINLINE inline void GenericTypeHandler<GenericType>::Merge(
+ const GenericType& from, GenericType* to) {
+ to->MergeFrom(from);
+}
+template <>
+void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from,
+ MessageLite* to);
+
+template <>
+inline void GenericTypeHandler<std::string>::Clear(std::string* value) {
+ value->clear();
+}
+template <>
+void GenericTypeHandler<std::string>::Merge(const std::string& from,
+ std::string* 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 std::string Type;
+ using Movable = IsMovable<Type>;
+
+ static inline std::string* New(Arena* arena) {
+ return Arena::Create<std::string>(arena);
+ }
+ static inline std::string* New(Arena* arena, std::string&& value) {
+ return Arena::Create<std::string>(arena, std::move(value));
+ }
+ static inline std::string* NewFromPrototype(const std::string*,
+ Arena* arena) {
+ return New(arena);
+ }
+ static inline Arena* GetOwningArena(std::string*) { return nullptr; }
+ static inline void Delete(std::string* value, Arena* arena) {
+ if (arena == nullptr) {
+ delete value;
+ }
+ }
+ static inline void Clear(std::string* value) { value->clear(); }
+ static inline void Merge(const std::string& from, std::string* to) {
+ *to = from;
+ }
+ static size_t SpaceUsedLong(const std::string& value) {
+ return sizeof(value) + StringSpaceUsedExcludingSelfLong(value);
+ }
+};
+
+} // namespace internal
+
+// RepeatedPtrField is like RepeatedField, but used for repeated strings or
+// Messages.
+template <typename Element>
+class RepeatedPtrField final : 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);
+
+ // Unlike std::vector, adding an element to a RepeatedPtrField doesn't always
+ // make a new element; it might re-use an element left over from when the
+ // field was Clear()'d or reize()'d smaller. For this reason, Add() is the
+ // fastest API for adding a new element.
+ Element* Add();
+
+ // `Add(std::move(value));` is equivalent to `*Add() = std::move(value);`
+ // It will either move-construct to the end of this field, or swap value
+ // with the new-or-recycled element at the end of this field. Note that
+ // this operation is very slow if this RepeatedPtrField is not on the
+ // same Arena, if any, as `value`.
+ void Add(Element&& value);
+
+ // Copying to the end of this RepeatedPtrField is slowest of all; it can't
+ // reliably copy-construct to the last element of this RepeatedPtrField, for
+ // example (unlike std::vector).
+ // We currently block this API. The right way to add to the end is to call
+ // Add() and modify the element it points to.
+ // If you must add an existing value, call `*Add() = value;`
+ void Add(const Element& value) = delete;
+
+ // 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);
+
+ // Removes the last element in the array.
+ // Ownership of the element is retained by the array.
+ void RemoveLast();
+
+ // Deletes elements with indices in the range [start .. start+num-1].
+ // Caution: 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);
+
+ // Reserves 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);
+
+ int Capacity() const;
+
+ // Gets the underlying array. This pointer is possibly invalidated by
+ // any add or remove operation.
+ //
+ // This API is deprecated. Instead of directly working with element array,
+ // use APIs in repeated_field_util.h; e.g. sorting, etc.
+ PROTOBUF_DEPRECATED_MSG("Use APIs in repeated_field_util.h")
+ Element** mutable_data();
+ const Element* const* data() const;
+
+ // Swaps entire contents with "other". If they are on separate arenas, then
+ // copies data.
+ void Swap(RepeatedPtrField* other);
+
+ // Swaps 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);
+
+ // Swaps 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.
+
+ // Adds 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);
+
+ // Removes and returns the last element, 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();
+
+ // Adds 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);
+
+ // Removes and returns the last element. Unlike ReleaseLast, the returned
+ // pointer is always to the original object. This may be in an arena, in
+ // which case it would have the arena's lifetime.
+ // Requires: current_size_ > 0
+ Element* UnsafeArenaReleaseLast();
+
+ // Extracts 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.
+
+ // Gets the number of cleared objects that are currently being kept
+ // around for reuse.
+ int ClearedCount() const;
+#ifndef PROTOBUF_FUTURE_BREAKING_CHANGES
+ // Adds 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 either the repeated field or |value| is
+ // on an arena; both cases will trigger a GOOGLE_DCHECK-failure.
+ void AddCleared(Element* value);
+ // Removes and returns a single element from the cleared pool, 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;
+
+ // Internal version of GetArena().
+ inline Arena* GetOwningArena() const;
+
+ // 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_;
+
+};
+
+// -------------------------------------------------------------------
+
+template <typename Element>
+class RepeatedPtrField<Element>::TypeHandler
+ : public internal::GenericTypeHandler<Element> {};
+
+template <>
+class RepeatedPtrField<std::string>::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.GetOwningArena()) {
+ 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 (GetOwningArena() != other.GetOwningArena()
+#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ || GetOwningArena() == 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 = GetOwningArena();
+#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(GetOwningArena() == 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;
+ GOOGLE_DCHECK_EQ(GetOwningArena(), other->GetOwningArena());
+ 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 Arena* RepeatedPtrField<Element>::GetOwningArena() const {
+ return RepeatedPtrFieldBase::GetOwningArena();
+}
+
+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) {}
+
+ // Allows "upcasting" from RepeatedPtrIterator<T**> to
+ // RepeatedPtrIterator<const T*const*>.
+ template <typename OtherElement,
+ typename std::enable_if<std::is_convertible<
+ OtherElement*, pointer>::value>::type* = nullptr>
+ RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
+ : it_(other.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
+ friend bool operator==(const iterator& x, const iterator& y) {
+ return x.it_ == y.it_;
+ }
+ friend bool operator!=(const iterator& x, const iterator& y) {
+ return x.it_ != y.it_;
+ }
+
+ // less_than_comparable
+ friend bool operator<(const iterator& x, const iterator& y) {
+ return x.it_ < y.it_;
+ }
+ friend bool operator<=(const iterator& x, const iterator& y) {
+ return x.it_ <= y.it_;
+ }
+ friend bool operator>(const iterator& x, const iterator& y) {
+ return x.it_ > y.it_;
+ }
+ friend bool operator>=(const iterator& x, const iterator& y) {
+ return x.it_ >= y.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
+ friend difference_type operator-(iterator it1, iterator it2) {
+ return it1.it_ - it2.it_;
+ }
+
+ private:
+ template <typename OtherElement>
+ friend class RepeatedPtrIterator;
+
+ // The internal iterator.
+ void* const* it_;
+};
+
+// Provides 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) {}
+
+ // Allows "upcasting" from RepeatedPtrOverPtrsIterator<T**> to
+ // RepeatedPtrOverPtrsIterator<const T*const*>.
+ template <
+ typename OtherElement, typename OtherVoidPtr,
+ typename std::enable_if<
+ std::is_convertible<OtherElement*, pointer>::value &&
+ std::is_convertible<OtherVoidPtr*, VoidPtr>::value>::type* = nullptr>
+ RepeatedPtrOverPtrsIterator(
+ const RepeatedPtrOverPtrsIterator<OtherElement, OtherVoidPtr>& other)
+ : it_(other.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
+ friend bool operator==(const iterator& x, const iterator& y) {
+ return x.it_ == y.it_;
+ }
+ friend bool operator!=(const iterator& x, const iterator& y) {
+ return x.it_ != y.it_;
+ }
+
+ // less_than_comparable
+ friend bool operator<(const iterator& x, const iterator& y) {
+ return x.it_ < y.it_;
+ }
+ friend bool operator<=(const iterator& x, const iterator& y) {
+ return x.it_ <= y.it_;
+ }
+ friend bool operator>(const iterator& x, const iterator& y) {
+ return x.it_ > y.it_;
+ }
+ friend bool operator>=(const iterator& x, const iterator& y) {
+ return x.it_ >= y.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
+ friend difference_type operator-(iterator it1, iterator it2) {
+ return it1.it_ - it2.it_;
+ }
+
+ private:
+ template <typename OtherElement, typename OtherVoidPtr>
+ friend class RepeatedPtrOverPtrsIterator;
+
+ // The internal iterator.
+ VoidPtr* it_;
+};
+
+} // 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);
+// Putting temp_field on the arena fails because the ownership transfers to the
+// arena at the "AddAllocated" call and is not released anymore causing a
+// double delete. This function uses UnsafeArenaAddAllocated to prevent 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<std::string>;
+
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/service.cc b/toolkit/components/protobuf/src/google/protobuf/service.cc
new file mode 100644
index 0000000000..53945684cb
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/service.h b/toolkit/components/protobuf/src/google/protobuf/service.h
new file mode 100644
index 0000000000..d288eb554a
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/service.h
@@ -0,0 +1,295 @@
+// 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
+
+// Must be included last.
+#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 std::string 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 std::string& 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/toolkit/components/protobuf/src/google/protobuf/source_context.pb.cc b/toolkit/components/protobuf/src/google/protobuf/source_context.pb.cc
new file mode 100644
index 0000000000..e7525e99cf
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/source_context.pb.cc
@@ -0,0 +1,297 @@
+// 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
+
+namespace _pb = ::PROTOBUF_NAMESPACE_ID;
+namespace _pbi = _pb::internal;
+
+PROTOBUF_NAMESPACE_OPEN
+PROTOBUF_CONSTEXPR SourceContext::SourceContext(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.file_name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct SourceContextDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR SourceContextDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~SourceContextDefaultTypeInternal() {}
+ union {
+ SourceContext _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 SourceContextDefaultTypeInternal _SourceContext_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto[1];
+static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr;
+static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr;
+
+const uint32_t 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, _impl_.file_name_),
+};
+static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::SourceContext)},
+};
+
+static const ::_pb::Message* const file_default_instances[] = {
+ &::PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_._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 ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_once;
+const ::_pbi::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 ::_pbi::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_PRIORITY2 static ::_pbi::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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceContext)
+}
+SourceContext::SourceContext(const SourceContext& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ SourceContext* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.file_name_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.file_name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.file_name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_file_name().empty()) {
+ _this->_impl_.file_name_.Set(from._internal_file_name(),
+ _this->GetArenaForAllocation());
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceContext)
+}
+
+inline void SourceContext::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.file_name_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+ _impl_.file_name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.file_name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+SourceContext::~SourceContext() {
+ // @@protoc_insertion_point(destructor:google.protobuf.SourceContext)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void SourceContext::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.file_name_.Destroy();
+}
+
+void SourceContext::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void SourceContext::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceContext)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.file_name_.ClearToEmpty();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* SourceContext::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.SourceContext.file_name"));
+ } 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)
+ uint32_t 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 = ::_pbi::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;
+
+ uint32_t 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, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceContext::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ SourceContext::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*SourceContext::GetClassData() const { return &_class_data_; }
+
+
+void SourceContext::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<SourceContext*>(&to_msg);
+ auto& from = static_cast<const SourceContext&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceContext)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (!from._internal_file_name().empty()) {
+ _this->_internal_set_file_name(from._internal_file_name());
+ }
+ _this->_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(
+ &_impl_.file_name_, lhs_arena,
+ &other->_impl_.file_name_, rhs_arena
+ );
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata SourceContext::GetMetadata() const {
+ return ::_pbi::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/toolkit/components/protobuf/src/google/protobuf/source_context.pb.h b/toolkit/components/protobuf/src/google/protobuf/source_context.pb.h
new file mode 100644
index 0000000000..e9c41bdea7
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/source_context.pb.h
@@ -0,0 +1,282 @@
+// 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 < 3021000
+#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 3021006 < 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_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 uint32_t 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 PROTOBUF_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) {
+ SourceContext::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& file_name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_file_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_file_name();
+ PROTOBUF_NODISCARD std::string* release_file_name();
+ void set_allocated_file_name(std::string* file_name);
+ private:
+ const std::string& _internal_file_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_file_name(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr file_name_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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() {
+ _impl_.file_name_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.file_name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceContext.file_name)
+}
+inline std::string* SourceContext::mutable_file_name() {
+ std::string* _s = _internal_mutable_file_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.SourceContext.file_name)
+ return _s;
+}
+inline const std::string& SourceContext::_internal_file_name() const {
+ return _impl_.file_name_.Get();
+}
+inline void SourceContext::_internal_set_file_name(const std::string& value) {
+
+ _impl_.file_name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* SourceContext::_internal_mutable_file_name() {
+
+ return _impl_.file_name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* SourceContext::release_file_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.SourceContext.file_name)
+ return _impl_.file_name_.Release();
+}
+inline void SourceContext::set_allocated_file_name(std::string* file_name) {
+ if (file_name != nullptr) {
+
+ } else {
+
+ }
+ _impl_.file_name_.SetAllocated(file_name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.file_name_.IsDefault()) {
+ _impl_.file_name_.Set("", 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/toolkit/components/protobuf/src/google/protobuf/source_context.proto b/toolkit/components/protobuf/src/google/protobuf/source_context.proto
new file mode 100644
index 0000000000..06bfc43a78
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/string_member_robber.h b/toolkit/components/protobuf/src/google/protobuf/string_member_robber.h
new file mode 100644
index 0000000000..a4c1051e01
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/string_member_robber.h
@@ -0,0 +1,38 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_STRING_MEMBER_ROBBER_H__
+#define GOOGLE_PROTOBUF_STRING_MEMBER_ROBBER_H__
+
+#include <string>
+#include <type_traits>
+
+
+#endif // GOOGLE_PROTOBUF_STRING_MEMBER_ROBBER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/struct.pb.cc b/toolkit/components/protobuf/src/google/protobuf/struct.pb.cc
new file mode 100644
index 0000000000..87c72d4aa4
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/struct.pb.cc
@@ -0,0 +1,1057 @@
+// 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
+
+namespace _pb = ::PROTOBUF_NAMESPACE_ID;
+namespace _pbi = _pb::internal;
+
+PROTOBUF_NAMESPACE_OPEN
+PROTOBUF_CONSTEXPR Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse(
+ ::_pbi::ConstantInitialized) {}
+struct Struct_FieldsEntry_DoNotUseDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR Struct_FieldsEntry_DoNotUseDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~Struct_FieldsEntry_DoNotUseDefaultTypeInternal() {}
+ union {
+ Struct_FieldsEntry_DoNotUse _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 Struct_FieldsEntry_DoNotUseDefaultTypeInternal _Struct_FieldsEntry_DoNotUse_default_instance_;
+PROTOBUF_CONSTEXPR Struct::Struct(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.fields_)*/{::_pbi::ConstantInitialized()}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct StructDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR StructDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~StructDefaultTypeInternal() {}
+ union {
+ Struct _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 StructDefaultTypeInternal _Struct_default_instance_;
+PROTOBUF_CONSTEXPR Value::Value(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.kind_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_._oneof_case_)*/{}} {}
+struct ValueDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR ValueDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~ValueDefaultTypeInternal() {}
+ union {
+ Value _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ValueDefaultTypeInternal _Value_default_instance_;
+PROTOBUF_CONSTEXPR ListValue::ListValue(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.values_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct ListValueDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR ListValueDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~ListValueDefaultTypeInternal() {}
+ union {
+ ListValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ListValueDefaultTypeInternal _ListValue_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fstruct_2eproto[4];
+static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto[1];
+static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto = nullptr;
+
+const uint32_t 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, _impl_.fields_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Value, _internal_metadata_),
+ ~0u, // no _extensions_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Value, _impl_._oneof_case_[0]),
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ ::_pbi::kInvalidFieldOffsetTag,
+ ::_pbi::kInvalidFieldOffsetTag,
+ ::_pbi::kInvalidFieldOffsetTag,
+ ::_pbi::kInvalidFieldOffsetTag,
+ ::_pbi::kInvalidFieldOffsetTag,
+ ::_pbi::kInvalidFieldOffsetTag,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Value, _impl_.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, _impl_.values_),
+};
+static const ::_pbi::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 const ::_pb::Message* const file_default_instances[] = {
+ &::PROTOBUF_NAMESPACE_ID::_Struct_FieldsEntry_DoNotUse_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_Struct_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_Value_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_._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 ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fstruct_2eproto_once;
+const ::_pbi::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 ::_pbi::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_PRIORITY2 static ::_pbi::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 ::_pbi::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) {
+ SharedCtor(arena, is_message_owned);
+ if (arena != nullptr && !is_message_owned) {
+ arena->OwnCustomDestructor(this, &Struct::ArenaDtor);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Struct)
+}
+Struct::Struct(const Struct& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Struct* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_.fields_)*/{}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _this->_impl_.fields_.MergeFrom(from._impl_.fields_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Struct)
+}
+
+inline void Struct::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ /*decltype(_impl_.fields_)*/{::_pbi::ArenaInitialized(), arena}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+Struct::~Struct() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Struct)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ ArenaDtor(this);
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Struct::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.fields_.Destruct();
+ _impl_.fields_.~MapField();
+}
+
+void Struct::ArenaDtor(void* object) {
+ Struct* _this = reinterpret_cast< Struct* >(object);
+ _this->_impl_.fields_.Destruct();
+}
+void Struct::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void Struct::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Struct)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.fields_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Struct::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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(&_impl_.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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // map<string, .google.protobuf.Value> fields = 1;
+ if (!this->_internal_fields().empty()) {
+ using MapType = ::_pb::Map<std::string, ::PROTOBUF_NAMESPACE_ID::Value>;
+ using WireHelper = Struct_FieldsEntry_DoNotUse::Funcs;
+ const auto& map_field = this->_internal_fields();
+ auto check_utf8 = [](const MapType::value_type& entry) {
+ (void)entry;
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
+ entry.first.data(), static_cast<int>(entry.first.length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Struct.FieldsEntry.key");
+ };
+
+ if (stream->IsSerializationDeterministic() && map_field.size() > 1) {
+ for (const auto& entry : ::_pbi::MapSorterPtr<MapType>(map_field)) {
+ target = WireHelper::InternalSerialize(1, entry.first, entry.second, target, stream);
+ check_utf8(entry);
+ }
+ } else {
+ for (const auto& entry : map_field) {
+ target = WireHelper::InternalSerialize(1, entry.first, entry.second, target, stream);
+ check_utf8(entry);
+ }
+ }
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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< std::string, ::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, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Struct::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Struct::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Struct::GetClassData() const { return &_class_data_; }
+
+
+void Struct::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Struct*>(&to_msg);
+ auto& from = static_cast<const Struct&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Struct)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.fields_.MergeFrom(from._impl_.fields_);
+ _this->_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_);
+ _impl_.fields_.InternalSwap(&other->_impl_.fields_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Struct::GetMetadata() const {
+ return ::_pbi::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->_impl_.kind_.struct_value_;
+}
+const ::PROTOBUF_NAMESPACE_ID::ListValue&
+Value::_Internal::list_value(const Value* msg) {
+ return *msg->_impl_.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::InternalGetOwningArena(struct_value);
+ if (message_arena != submessage_arena) {
+ struct_value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, struct_value, submessage_arena);
+ }
+ set_has_struct_value();
+ _impl_.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::InternalGetOwningArena(list_value);
+ if (message_arena != submessage_arena) {
+ list_value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, list_value, submessage_arena);
+ }
+ set_has_list_value();
+ _impl_.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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Value)
+}
+Value::Value(const Value& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Value* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.kind_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_._oneof_case_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ clear_has_kind();
+ switch (from.kind_case()) {
+ case kNullValue: {
+ _this->_internal_set_null_value(from._internal_null_value());
+ break;
+ }
+ case kNumberValue: {
+ _this->_internal_set_number_value(from._internal_number_value());
+ break;
+ }
+ case kStringValue: {
+ _this->_internal_set_string_value(from._internal_string_value());
+ break;
+ }
+ case kBoolValue: {
+ _this->_internal_set_bool_value(from._internal_bool_value());
+ break;
+ }
+ case kStructValue: {
+ _this->_internal_mutable_struct_value()->::PROTOBUF_NAMESPACE_ID::Struct::MergeFrom(
+ from._internal_struct_value());
+ break;
+ }
+ case kListValue: {
+ _this->_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(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.kind_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ , /*decltype(_impl_._oneof_case_)*/{}
+ };
+ clear_has_kind();
+}
+
+Value::~Value() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Value)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Value::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ if (has_kind()) {
+ clear_kind();
+ }
+}
+
+void Value::SetCachedSize(int size) const {
+ _impl_._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: {
+ _impl_.kind_.string_value_.Destroy();
+ break;
+ }
+ case kBoolValue: {
+ // No need to clear
+ break;
+ }
+ case kStructValue: {
+ if (GetArenaForAllocation() == nullptr) {
+ delete _impl_.kind_.struct_value_;
+ }
+ break;
+ }
+ case kListValue: {
+ if (GetArenaForAllocation() == nullptr) {
+ delete _impl_.kind_.list_value_;
+ }
+ break;
+ }
+ case KIND_NOT_SET: {
+ break;
+ }
+ }
+ _impl_._oneof_case_[0] = KIND_NOT_SET;
+}
+
+
+void Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Value)
+ uint32_t 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, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // .google.protobuf.NullValue null_value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ uint64_t 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Value.string_value"));
+ } 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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // .google.protobuf.NullValue null_value = 1;
+ if (_internal_has_null_value()) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteEnumToArray(
+ 1, this->_internal_null_value(), target);
+ }
+
+ // double number_value = 2;
+ if (_internal_has_number_value()) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::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 = ::_pbi::WireFormatLite::WriteBoolToArray(4, this->_internal_bool_value(), target);
+ }
+
+ // .google.protobuf.Struct struct_value = 5;
+ if (_internal_has_struct_value()) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(5, _Internal::struct_value(this),
+ _Internal::struct_value(this).GetCachedSize(), target, stream);
+ }
+
+ // .google.protobuf.ListValue list_value = 6;
+ if (_internal_has_list_value()) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(6, _Internal::list_value(this),
+ _Internal::list_value(this).GetCachedSize(), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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 +
+ ::_pbi::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(
+ *_impl_.kind_.struct_value_);
+ break;
+ }
+ // .google.protobuf.ListValue list_value = 6;
+ case kListValue: {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *_impl_.kind_.list_value_);
+ break;
+ }
+ case KIND_NOT_SET: {
+ break;
+ }
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Value::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Value::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Value::GetClassData() const { return &_class_data_; }
+
+
+void Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Value*>(&to_msg);
+ auto& from = static_cast<const Value&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Value)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ switch (from.kind_case()) {
+ case kNullValue: {
+ _this->_internal_set_null_value(from._internal_null_value());
+ break;
+ }
+ case kNumberValue: {
+ _this->_internal_set_number_value(from._internal_number_value());
+ break;
+ }
+ case kStringValue: {
+ _this->_internal_set_string_value(from._internal_string_value());
+ break;
+ }
+ case kBoolValue: {
+ _this->_internal_set_bool_value(from._internal_bool_value());
+ break;
+ }
+ case kStructValue: {
+ _this->_internal_mutable_struct_value()->::PROTOBUF_NAMESPACE_ID::Struct::MergeFrom(
+ from._internal_struct_value());
+ break;
+ }
+ case kListValue: {
+ _this->_internal_mutable_list_value()->::PROTOBUF_NAMESPACE_ID::ListValue::MergeFrom(
+ from._internal_list_value());
+ break;
+ }
+ case KIND_NOT_SET: {
+ break;
+ }
+ }
+ _this->_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(_impl_.kind_, other->_impl_.kind_);
+ swap(_impl_._oneof_case_[0], other->_impl_._oneof_case_[0]);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Value::GetMetadata() const {
+ return ::_pbi::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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.ListValue)
+}
+ListValue::ListValue(const ListValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ ListValue* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.values_){from._impl_.values_}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.ListValue)
+}
+
+inline void ListValue::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.values_){arena}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+ListValue::~ListValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.ListValue)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void ListValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.values_.~RepeatedPtrField();
+}
+
+void ListValue::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void ListValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.ListValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.values_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* ListValue::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.Value values = 1;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_values_size()); i < n; i++) {
+ const auto& repfield = this->_internal_values(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(1, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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->_impl_.values_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ListValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ ListValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ListValue::GetClassData() const { return &_class_data_; }
+
+
+void ListValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<ListValue*>(&to_msg);
+ auto& from = static_cast<const ListValue&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ListValue)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.values_.MergeFrom(from._impl_.values_);
+ _this->_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_);
+ _impl_.values_.InternalSwap(&other->_impl_.values_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata ListValue::GetMetadata() const {
+ return ::_pbi::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/toolkit/components/protobuf/src/google/protobuf/struct.pb.h b/toolkit/components/protobuf/src/google/protobuf/struct.pb.h
new file mode 100644
index 0000000000..ac2d9716dd
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/struct.pb.h
@@ -0,0 +1,1177 @@
+// 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 < 3021000
+#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 3021006 < 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_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 uint32_t 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<int32_t>::min(),
+ NullValue_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::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 std::string& NullValue_Name(T enum_t_value) {
+ static_assert(::std::is_same<T, NullValue>::value ||
+ ::std::is_integral<T>::value,
+ "Incorrect type passed to function NullValue_Name.");
+ return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
+ NullValue_descriptor(), enum_t_value);
+}
+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,
+ std::string, ::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,
+ std::string, ::PROTOBUF_NAMESPACE_ID::Value,
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING,
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE> SuperType;
+ Struct_FieldsEntry_DoNotUse();
+ explicit PROTOBUF_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(std::string* 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;
+ friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto;
+};
+
+// -------------------------------------------------------------------
+
+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 PROTOBUF_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) {
+ Struct::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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< std::string, ::PROTOBUF_NAMESPACE_ID::Value >&
+ _internal_fields() const;
+ ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >*
+ _internal_mutable_fields();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >&
+ fields() const;
+ ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::MapField<
+ Struct_FieldsEntry_DoNotUse,
+ std::string, ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ Value::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& string_value() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_string_value(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_string_value();
+ PROTOBUF_NODISCARD std::string* release_string_value();
+ void set_allocated_string_value(std::string* string_value);
+ private:
+ const std::string& _internal_string_value() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_string_value(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ 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_;
+ uint32_t _oneof_case_[1];
+
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ ListValue::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value > values_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 _impl_.fields_.size();
+}
+inline int Struct::fields_size() const {
+ return _internal_fields_size();
+}
+inline void Struct::clear_fields() {
+ _impl_.fields_.Clear();
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >&
+Struct::_internal_fields() const {
+ return _impl_.fields_.GetMap();
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >&
+Struct::fields() const {
+ // @@protoc_insertion_point(field_map:google.protobuf.Struct.fields)
+ return _internal_fields();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >*
+Struct::_internal_mutable_fields() {
+ return _impl_.fields_.MutableMap();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::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() {
+ _impl_._oneof_case_[0] = kNullValue;
+}
+inline void Value::clear_null_value() {
+ if (_internal_has_null_value()) {
+ _impl_.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 >(_impl_.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();
+ }
+ _impl_.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() {
+ _impl_._oneof_case_[0] = kNumberValue;
+}
+inline void Value::clear_number_value() {
+ if (_internal_has_number_value()) {
+ _impl_.kind_.number_value_ = 0;
+ clear_has_kind();
+ }
+}
+inline double Value::_internal_number_value() const {
+ if (_internal_has_number_value()) {
+ return _impl_.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();
+ }
+ _impl_.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() {
+ _impl_._oneof_case_[0] = kStringValue;
+}
+inline void Value::clear_string_value() {
+ if (_internal_has_string_value()) {
+ _impl_.kind_.string_value_.Destroy();
+ clear_has_kind();
+ }
+}
+inline const std::string& 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();
+ _impl_.kind_.string_value_.InitDefault();
+ }
+ _impl_.kind_.string_value_.Set( static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value)
+}
+inline std::string* Value::mutable_string_value() {
+ std::string* _s = _internal_mutable_string_value();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Value.string_value)
+ return _s;
+}
+inline const std::string& Value::_internal_string_value() const {
+ if (_internal_has_string_value()) {
+ return _impl_.kind_.string_value_.Get();
+ }
+ return ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited();
+}
+inline void Value::_internal_set_string_value(const std::string& value) {
+ if (!_internal_has_string_value()) {
+ clear_kind();
+ set_has_string_value();
+ _impl_.kind_.string_value_.InitDefault();
+ }
+ _impl_.kind_.string_value_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Value::_internal_mutable_string_value() {
+ if (!_internal_has_string_value()) {
+ clear_kind();
+ set_has_string_value();
+ _impl_.kind_.string_value_.InitDefault();
+ }
+ return _impl_.kind_.string_value_.Mutable( GetArenaForAllocation());
+}
+inline std::string* Value::release_string_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Value.string_value)
+ if (_internal_has_string_value()) {
+ clear_has_kind();
+ return _impl_.kind_.string_value_.Release();
+ } else {
+ return nullptr;
+ }
+}
+inline void Value::set_allocated_string_value(std::string* string_value) {
+ if (has_kind()) {
+ clear_kind();
+ }
+ if (string_value != nullptr) {
+ set_has_string_value();
+ _impl_.kind_.string_value_.InitAllocated(string_value, GetArenaForAllocation());
+ }
+ // @@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() {
+ _impl_._oneof_case_[0] = kBoolValue;
+}
+inline void Value::clear_bool_value() {
+ if (_internal_has_bool_value()) {
+ _impl_.kind_.bool_value_ = false;
+ clear_has_kind();
+ }
+}
+inline bool Value::_internal_bool_value() const {
+ if (_internal_has_bool_value()) {
+ return _impl_.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();
+ }
+ _impl_.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() {
+ _impl_._oneof_case_[0] = kStructValue;
+}
+inline void Value::clear_struct_value() {
+ if (_internal_has_struct_value()) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete _impl_.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 = _impl_.kind_.struct_value_;
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+ _impl_.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()
+ ? *_impl_.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 = _impl_.kind_.struct_value_;
+ _impl_.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();
+ _impl_.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();
+ _impl_.kind_.struct_value_ = CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Struct >(GetArenaForAllocation());
+ }
+ return _impl_.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() {
+ _impl_._oneof_case_[0] = kListValue;
+}
+inline void Value::clear_list_value() {
+ if (_internal_has_list_value()) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete _impl_.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 = _impl_.kind_.list_value_;
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+ _impl_.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()
+ ? *_impl_.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 = _impl_.kind_.list_value_;
+ _impl_.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();
+ _impl_.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();
+ _impl_.kind_.list_value_ = CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ListValue >(GetArenaForAllocation());
+ }
+ return _impl_.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() {
+ _impl_._oneof_case_[0] = KIND_NOT_SET;
+}
+inline Value::KindCase Value::kind_case() const {
+ return Value::KindCase(_impl_._oneof_case_[0]);
+}
+// -------------------------------------------------------------------
+
+// ListValue
+
+// repeated .google.protobuf.Value values = 1;
+inline int ListValue::_internal_values_size() const {
+ return _impl_.values_.size();
+}
+inline int ListValue::values_size() const {
+ return _internal_values_size();
+}
+inline void ListValue::clear_values() {
+ _impl_.values_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Value* ListValue::mutable_values(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.ListValue.values)
+ return _impl_.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 &_impl_.values_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Value& ListValue::_internal_values(int index) const {
+ return _impl_.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 _impl_.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 _impl_.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/toolkit/components/protobuf/src/google/protobuf/struct.proto b/toolkit/components/protobuf/src/google/protobuf/struct.proto
new file mode 100644
index 0000000000..0ac843ca08
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/stubs/bytestream.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/bytestream.cc
new file mode 100644
index 0000000000..980d6f6cfc
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/stubs/bytestream.h b/toolkit/components/protobuf/src/google/protobuf/stubs/bytestream.h
new file mode 100644
index 0000000000..c7a48dea54
--- /dev/null
+++ b/toolkit/components/protobuf/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(std::string* dest) : dest_(dest) {}
+ virtual void Append(const char* data, size_t n) override;
+
+ private:
+ std::string* 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/toolkit/components/protobuf/src/google/protobuf/stubs/callback.h b/toolkit/components/protobuf/src/google/protobuf/stubs/callback.h
new file mode 100644
index 0000000000..43d546d199
--- /dev/null
+++ b/toolkit/components/protobuf/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(std::string s);
+// NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string
+// NewCallback(&Foo, std::string("foo")); // WORKS
+// Also note that the arguments cannot be references:
+// void Foo(const std::string& s);
+// std::string 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/toolkit/components/protobuf/src/google/protobuf/stubs/casts.h b/toolkit/components/protobuf/src/google/protobuf/stubs/casts.h
new file mode 100644
index 0000000000..ad29dac1f8
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/stubs/common.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/common.cc
new file mode 100644
index 0000000000..e0a807ffbb
--- /dev/null
+++ b/toolkit/components/protobuf/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 << "\".)";
+ }
+}
+
+std::string 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 std::string& 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 std::string& 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 std::string& /* message */) {
+ // Nothing.
+}
+
+static LogHandler* log_handler_ = &DefaultLogHandler;
+static std::atomic<int> log_silencer_count_ = ATOMIC_VAR_INIT(0);
+
+LogMessage& LogMessage::operator<<(const std::string& 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_t ghtonl(uint32_t x) {
+ union {
+ uint32_t result;
+ uint8_t result_array[4];
+ };
+ result_array[0] = static_cast<uint8_t>(x >> 24);
+ result_array[1] = static_cast<uint8_t>((x >> 16) & 0xFF);
+ result_array[2] = static_cast<uint8_t>((x >> 8) & 0xFF);
+ result_array[3] = static_cast<uint8_t>(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/toolkit/components/protobuf/src/google/protobuf/stubs/common.h b/toolkit/components/protobuf/src/google/protobuf/stubs/common.h
new file mode 100644
index 0000000000..58739784db
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/stubs/common.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.
+
+// 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 <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
+
+#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 3021006
+
+// 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 = 3021000;
+
+// The minimum protoc version which works with the current version of the
+// headers.
+#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3021000
+
+// The minimum header version which works with the current version of
+// protoc. This constant should only be used in VerifyVersion().
+static const int kMinHeaderVersionForProtoc = 3021000;
+
+// 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.
+std::string 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 std::string& 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 std::string& message() const { return message_; }
+
+ private:
+ const char* filename_;
+ const int line_;
+ const std::string message_;
+};
+#endif
+
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMMON_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/hash.h b/toolkit/components/protobuf/src/google/protobuf/stubs/hash.h
new file mode 100644
index 0000000000..a7ec068074
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/stubs/hash.h
@@ -0,0 +1,114 @@
+// 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>
+
+# 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<std::string> {
+ inline size_t operator()(const std::string& 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 std::string& a, const std::string& 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/toolkit/components/protobuf/src/google/protobuf/stubs/int128.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/int128.cc
new file mode 100644
index 0000000000..a151cfb554
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/stubs/int128.cc
@@ -0,0 +1,193 @@
+// 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 = {uint64_t{0xFFFFFFFFFFFFFFFFu},
+ uint64_t{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_t n) {
+ GOOGLE_DCHECK_NE(0, n);
+ int pos = 0;
+ STEP(uint64_t, n, pos, 0x20);
+ uint32_t n32 = n;
+ STEP(uint32_t, n32, pos, 0x10);
+ STEP(uint32_t, n32, pos, 0x08);
+ STEP(uint32_t, n32, pos, 0x04);
+ return pos + ((uint64_t{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_t 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, &quotient, &remainder);
+ *this = quotient;
+ return *this;
+}
+uint128& uint128::operator%=(const uint128& divisor) {
+ uint128 quotient = 0;
+ uint128 remainder = 0;
+ DivModImpl(*this, divisor, &quotient, &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_t>(uint64_t{0x1000000000000000u}); // 16^15
+ div_base_log = 15;
+ break;
+ case std::ios::oct:
+ div = static_cast<uint64_t>(
+ uint64_t{01000000000000000000000u}); // 8^21
+ div_base_log = 21;
+ break;
+ default: // std::ios::dec
+ div = static_cast<uint64_t>(
+ uint64_t{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);
+ auto repSize = static_cast<std::streamsize>(rep.size());
+ if (width > repSize) {
+ if ((flags & std::ios::adjustfield) == std::ios::left) {
+ rep.append(width - repSize, o.fill());
+ } else {
+ rep.insert(static_cast<std::string::size_type>(0), width - repSize,
+ 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/toolkit/components/protobuf/src/google/protobuf/stubs/int128.h b/toolkit/components/protobuf/src/google/protobuf/stubs/int128.h
new file mode 100644
index 0000000000..92d7bdffa4
--- /dev/null
+++ b/toolkit/components/protobuf/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_t top, uint64_t bottom);
+#ifndef SWIG
+ UINT128_CONSTEXPR uint128(int bottom);
+ UINT128_CONSTEXPR uint128(uint32_t bottom); // Top 96 bits = 0
+#endif
+ UINT128_CONSTEXPR uint128(uint64_t bottom); // hi_ = 0
+ UINT128_CONSTEXPR uint128(const uint128_pod &val);
+
+ // Trivial copy constructor, assignment operator and destructor.
+
+ void Initialize(uint64_t top, uint64_t 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_t Uint128Low64(const uint128& v);
+ friend uint64_t 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_t lo_;
+ uint64_t hi_;
+
+ // Not implemented, just declared for catching automatic type conversions.
+ uint128(uint8_t);
+ uint128(uint16_t);
+ 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_t hi;
+ uint64_t 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_t Uint128Low64(const uint128& v) { return v.lo_; }
+inline uint64_t 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_t top, uint64_t 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_t bottom)
+ : lo_(bottom), hi_(0) {}
+#ifndef SWIG
+inline UINT128_CONSTEXPR uint128::uint128(uint32_t bottom)
+ : lo_(bottom), hi_(0) {}
+inline UINT128_CONSTEXPR uint128::uint128(int bottom)
+ : lo_(bottom), hi_(static_cast<int64_t>((bottom < 0) ? -1 : 0)) {}
+#endif
+
+#undef UINT128_CONSTEXPR
+
+inline void uint128::Initialize(uint64_t top, uint64_t 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_t hi_flip = ~Uint128High64(val);
+ const uint64_t lo_flip = ~Uint128Low64(val);
+ const uint64_t 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_t new_hi = (Uint128High64(val) << amount) |
+ (Uint128Low64(val) >> (64 - amount));
+ uint64_t 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_t new_hi = Uint128High64(val) >> amount;
+ uint64_t 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_t 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_t a96 = hi_ >> 32;
+ uint64_t a64 = hi_ & 0xffffffffu;
+ uint64_t a32 = lo_ >> 32;
+ uint64_t a00 = lo_ & 0xffffffffu;
+ uint64_t b96 = b.hi_ >> 32;
+ uint64_t b64 = b.hi_ & 0xffffffffu;
+ uint64_t b32 = b.lo_ >> 32;
+ uint64_t 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_t c96 = a96 * b00 + a64 * b32 + a32 * b64 + a00 * b96;
+ uint64_t 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/toolkit/components/protobuf/src/google/protobuf/stubs/logging.h b/toolkit/components/protobuf/src/google/protobuf/stubs/logging.h
new file mode 100644
index 0000000000..8ecc2fa0f1
--- /dev/null
+++ b/toolkit/components/protobuf/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 std::string& 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_;
+ std::string 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 std::string& 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/toolkit/components/protobuf/src/google/protobuf/stubs/macros.h b/toolkit/components/protobuf/src/google/protobuf/stubs/macros.h
new file mode 100644
index 0000000000..ae9a8b987f
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/stubs/map_util.h b/toolkit/components/protobuf/src/google/protobuf/stubs/map_util.h
new file mode 100644
index 0000000000..24e098ad1b
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/stubs/mathutil.h b/toolkit/components/protobuf/src/google/protobuf/stubs/mathutil.h
new file mode 100644
index 0000000000..1d16bcedb2
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/stubs/mutex.h b/toolkit/components/protobuf/src/google/protobuf/stubs/mutex.h
new file mode 100644
index 0000000000..c4599913be
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/stubs/once.h b/toolkit/components/protobuf/src/google/protobuf/stubs/once.h
new file mode 100644
index 0000000000..070d36d193
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h b/toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h
new file mode 100644
index 0000000000..24799600dc
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/stubs/port.h b/toolkit/components/protobuf/src/google/protobuf/stubs/port.h
new file mode 100644
index 0000000000..b074cb1630
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/stubs/port.h
@@ -0,0 +1,413 @@
+// 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 <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__))
+#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
+
+namespace google {
+namespace protobuf {
+
+using ConstStringParam = const std::string &;
+
+typedef unsigned int uint;
+
+typedef int8_t int8;
+typedef int16_t int16;
+typedef int32_t int32;
+typedef int64_t int64;
+
+typedef uint8_t uint8;
+typedef uint16_t uint16;
+typedef uint32_t uint32;
+typedef uint64_t uint64;
+
+static const int32 kint32max = 0x7FFFFFFF;
+static const int32 kint32min = -kint32max - 1;
+static const int64 kint64max = int64_t{0x7FFFFFFFFFFFFFFF};
+static const int64 kint64min = -kint64max - 1;
+static const uint32 kuint32max = 0xFFFFFFFFu;
+static const uint64 kuint64max = uint64_t{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);
+uint32_t __sanitizer_unaligned_load32(const void *p);
+uint64_t __sanitizer_unaligned_load64(const void *p);
+void __sanitizer_unaligned_store16(void *p, uint16_t v);
+void __sanitizer_unaligned_store32(void *p, uint32_t v);
+void __sanitizer_unaligned_store64(void *p, uint64_t v);
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+inline uint16_t GOOGLE_UNALIGNED_LOAD16(const void *p) {
+ return __sanitizer_unaligned_load16(p);
+}
+
+inline uint32_t GOOGLE_UNALIGNED_LOAD32(const void *p) {
+ return __sanitizer_unaligned_load32(p);
+}
+
+inline uint64_t GOOGLE_UNALIGNED_LOAD64(const void *p) {
+ return __sanitizer_unaligned_load64(p);
+}
+
+inline void GOOGLE_UNALIGNED_STORE16(void *p, uint16_t v) {
+ __sanitizer_unaligned_store16(p, v);
+}
+
+inline void GOOGLE_UNALIGNED_STORE32(void *p, uint32_t v) {
+ __sanitizer_unaligned_store32(p, v);
+}
+
+inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64_t 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_t *>(_p))
+#define GOOGLE_UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32_t *>(_p))
+#define GOOGLE_UNALIGNED_LOAD64(_p) (*reinterpret_cast<const uint64_t *>(_p))
+
+#define GOOGLE_UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16_t *>(_p) = (_val))
+#define GOOGLE_UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32_t *>(_p) = (_val))
+#define GOOGLE_UNALIGNED_STORE64(_p, _val) (*reinterpret_cast<uint64_t *>(_p) = (_val))
+
+#else
+inline uint16_t GOOGLE_UNALIGNED_LOAD16(const void *p) {
+ uint16_t t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline uint32_t GOOGLE_UNALIGNED_LOAD32(const void *p) {
+ uint32_t t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline uint64_t GOOGLE_UNALIGNED_LOAD64(const void *p) {
+ uint64_t t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline void GOOGLE_UNALIGNED_STORE16(void *p, uint16_t v) {
+ memcpy(p, &v, sizeof v);
+}
+
+inline void GOOGLE_UNALIGNED_STORE32(void *p, uint32_t v) {
+ memcpy(p, &v, sizeof v);
+}
+
+inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64_t 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_t bswap_16(uint16_t x) {
+ return static_cast<uint16_t>(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8));
+}
+#define bswap_16(x) bswap_16(x)
+#endif
+
+#ifndef bswap_32
+static inline uint32_t bswap_32(uint32_t 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_t bswap_64(uint64_t x) {
+ return (((x & uint64_t{0xFFu}) << 56) | ((x & uint64_t{0xFF00u}) << 40) |
+ ((x & uint64_t{0xFF0000u}) << 24) |
+ ((x & uint64_t{0xFF000000u}) << 8) |
+ ((x & uint64_t{0xFF00000000u}) >> 8) |
+ ((x & uint64_t{0xFF0000000000u}) >> 24) |
+ ((x & uint64_t{0xFF000000000000u}) >> 40) |
+ ((x & uint64_t{0xFF00000000000000u}) >> 56));
+}
+#define bswap_64(x) bswap_64(x)
+#endif
+
+#endif
+
+// ===================================================================
+// from google3/util/bits/bits.h
+
+class Bits {
+ public:
+ static uint32_t Log2FloorNonZero(uint32_t n) {
+#if defined(__GNUC__)
+ return 31 ^ static_cast<uint32_t>(__builtin_clz(n));
+#elif defined(_MSC_VER)
+ unsigned long where;
+ _BitScanReverse(&where, n);
+ return where;
+#else
+ return Log2FloorNonZero_Portable(n);
+#endif
+ }
+
+ static uint32_t Log2FloorNonZero64(uint64_t 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_t>(__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_t n) {
+ if (n == 0)
+ return -1;
+ int log = 0;
+ uint32_t value = n;
+ for (int i = 4; i >= 0; --i) {
+ int shift = (1 << i);
+ uint32_t x = value >> shift;
+ if (x != 0) {
+ value = x;
+ log += shift;
+ }
+ }
+ assert(value == 1);
+ return log;
+ }
+
+ static int Log2FloorNonZero64_Portable(uint64_t n) {
+ const uint32_t topbits = static_cast<uint32_t>(n >> 32);
+ if (topbits == 0) {
+ // Top bits are zero, so scan in bottom bits
+ return static_cast<int>(Log2FloorNonZero(static_cast<uint32_t>(n)));
+ } else {
+ return 32 + static_cast<int>(Log2FloorNonZero(topbits));
+ }
+ }
+};
+
+// ===================================================================
+// from google3/util/endian/endian.h
+PROTOBUF_EXPORT uint32_t ghtonl(uint32_t x);
+
+class BigEndian {
+ public:
+#ifdef PROTOBUF_LITTLE_ENDIAN
+
+ static uint16_t FromHost16(uint16_t x) { return bswap_16(x); }
+ static uint16_t ToHost16(uint16_t x) { return bswap_16(x); }
+
+ static uint32_t FromHost32(uint32_t x) { return bswap_32(x); }
+ static uint32_t ToHost32(uint32_t x) { return bswap_32(x); }
+
+ static uint64_t FromHost64(uint64_t x) { return bswap_64(x); }
+ static uint64_t ToHost64(uint64_t x) { return bswap_64(x); }
+
+ static bool IsLittleEndian() { return true; }
+
+#else
+
+ static uint16_t FromHost16(uint16_t x) { return x; }
+ static uint16_t ToHost16(uint16_t x) { return x; }
+
+ static uint32_t FromHost32(uint32_t x) { return x; }
+ static uint32_t ToHost32(uint32_t x) { return x; }
+
+ static uint64_t FromHost64(uint64_t x) { return x; }
+ static uint64_t ToHost64(uint64_t x) { return x; }
+
+ static bool IsLittleEndian() { return false; }
+
+#endif /* ENDIAN */
+
+ // Functions to do unaligned loads and stores in big-endian order.
+ static uint16_t Load16(const void *p) {
+ return ToHost16(GOOGLE_UNALIGNED_LOAD16(p));
+ }
+
+ static void Store16(void *p, uint16_t v) {
+ GOOGLE_UNALIGNED_STORE16(p, FromHost16(v));
+ }
+
+ static uint32_t Load32(const void *p) {
+ return ToHost32(GOOGLE_UNALIGNED_LOAD32(p));
+ }
+
+ static void Store32(void *p, uint32_t v) {
+ GOOGLE_UNALIGNED_STORE32(p, FromHost32(v));
+ }
+
+ static uint64_t Load64(const void *p) {
+ return ToHost64(GOOGLE_UNALIGNED_LOAD64(p));
+ }
+
+ static void Store64(void *p, uint64_t 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/toolkit/components/protobuf/src/google/protobuf/stubs/status.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/status.cc
new file mode 100644
index 0000000000..f5c0fa48f1
--- /dev/null
+++ b/toolkit/components/protobuf/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 std::string 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_;
+}
+
+std::string 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/toolkit/components/protobuf/src/google/protobuf/stubs/status.h b/toolkit/components/protobuf/src/google/protobuf/stubs/status.h
new file mode 100644
index 0000000000..c858cf6239
--- /dev/null
+++ b/toolkit/components/protobuf/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.
+ std::string ToString() const;
+
+ private:
+ StatusCode error_code_;
+ std::string 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/toolkit/components/protobuf/src/google/protobuf/stubs/status_macros.h b/toolkit/components/protobuf/src/google/protobuf/stubs/status_macros.h
new file mode 100644
index 0000000000..407ff4c280
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/stubs/statusor.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/statusor.cc
new file mode 100644
index 0000000000..9c0a1782a8
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/stubs/statusor.h b/toolkit/components/protobuf/src/google/protobuf/stubs/statusor.h
new file mode 100644
index 0000000000..20e603ea04
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/stubs/stl_util.h b/toolkit/components/protobuf/src/google/protobuf/stubs/stl_util.h
new file mode 100644
index 0000000000..e6260d0760
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/stubs/stl_util.h
@@ -0,0 +1,90 @@
+// 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>
+
+// Must be last.
+#include <google/protobuf/port_def.inc> // NOLINT
+
+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(std::string* s, size_t new_size) {
+ s->resize(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(std::string* 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<size_t>(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(std::string* str) {
+ // DO NOT USE const_cast<char*>(str->data())! See the unittest for why.
+ return str->empty() ? nullptr : &*str->begin();
+}
+
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc> // NOLINT
+
+#endif // GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/stringpiece.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/stringpiece.cc
new file mode 100644
index 0000000000..71880464c7
--- /dev/null
+++ b/toolkit/components/protobuf/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(std::string* target) const {
+ target->assign(ptr_, length_);
+}
+
+void StringPiece::AppendToString(std::string* 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/toolkit/components/protobuf/src/google/protobuf/stubs/stringpiece.h b/toolkit/components/protobuf/src/google/protobuf/stubs/stringpiece.h
new file mode 100644
index 0000000000..c63e25b254
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/stubs/stringpiece.h
@@ -0,0 +1,402 @@
+// 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));
+ }
+ }
+
+ template <class Allocator>
+ StringPiece( // NOLINT(runtime/explicit)
+ const std::basic_string<char, std::char_traits<char>, Allocator>& str)
+ : ptr_(str.data()), length_(0) {
+ length_ = CheckSize(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;
+ }
+
+ std::string 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.
+ std::string ToString() const {
+ if (ptr_ == nullptr) return "";
+ return std::string(data(), static_cast<size_type>(size()));
+ }
+
+ explicit operator std::string() const { return ToString(); }
+
+ void CopyToString(std::string* target) const;
+ void AppendToString(std::string* 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/toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.cc
new file mode 100644
index 0000000000..a6ad4c0da4
--- /dev/null
+++ b/toolkit/components/protobuf/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(std::string* 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;
+}
+
+std::string StringPrintf(const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ std::string result;
+ StringAppendV(&result, format, ap);
+ va_end(ap);
+ return result;
+}
+
+const std::string& SStringPrintf(std::string* dst, const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ dst->clear();
+ StringAppendV(dst, format, ap);
+ va_end(ap);
+ return *dst;
+}
+
+void StringAppendF(std::string* 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' };
+
+std::string StringPrintfVector(const char* format,
+ const std::vector<std::string>& 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/toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.h b/toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.h
new file mode 100644
index 0000000000..e3858be130
--- /dev/null
+++ b/toolkit/components/protobuf/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 std::string StringPrintf(const char* format, ...);
+
+// Store result into a supplied string and return it
+PROTOBUF_EXPORT extern const std::string& SStringPrintf(std::string* dst,
+ const char* format,
+ ...);
+
+// Append result to a supplied string
+PROTOBUF_EXPORT extern void StringAppendF(std::string* 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(std::string* 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 std::string StringPrintfVector(
+ const char* format, const std::vector<std::string>& v);
+
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H
diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/structurally_valid.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/structurally_valid.cc
new file mode 100644
index 0000000000..a535736583
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/stubs/structurally_valid.cc
@@ -0,0 +1,617 @@
+// 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_t delete_bytes;
+ uint8_t add_bytes;
+ uint16_t 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_t state0;
+ const uint32_t state0_size;
+ const uint32_t total_size;
+ const int max_expand;
+ const int entry_shift;
+ const int bytes_per_entry;
+ const uint32_t losub;
+ const uint32_t hiadd;
+ const uint8_t* state_table;
+ const RemapEntry* remap_base;
+ const uint8_t* remap_string;
+ const uint8_t* 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_t 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_t* Tbl) {
+ const uint8_t* Tbl0 = &st->state_table[st->state0];
+ return (static_cast<uint32_t>(Tbl - Tbl0) < st->state0_size);
+}
+
+namespace {
+
+// 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_t* isrc = reinterpret_cast<const uint8_t*>(str);
+ const uint8_t* src = isrc;
+ const uint8_t* srclimit = isrc + str_length;
+ const uint8_t* srclimit8 = str_length < 7 ? isrc : srclimit - 7;
+ const uint8_t* Tbl_0 = &st->state_table[st->state0];
+
+ DoAgain:
+ // Do state-table scan
+ int e = 0;
+ uint8_t c;
+ const uint8_t* Tbl2 = &st->fast_state[0];
+ const uint32_t losub = st->losub;
+ const uint32_t 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_t s0123 = (reinterpret_cast<const uint32_t *>(src))[0];
+ uint32_t s4567 = (reinterpret_cast<const uint32_t *>(src))[1];
+ src += 8;
+ // This is a fast range check for all bytes in [lowsub..0x80-hiadd)
+ uint32_t 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_t* 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_t* isrc = reinterpret_cast<const uint8_t*>(str);
+ const uint8_t* src = isrc;
+ const uint8_t* srclimit = isrc + str_length;
+ const uint8_t* 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_t*>(src)[0] |
+ reinterpret_cast<const uint32_t*>(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.
+
+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/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.cc
new file mode 100644
index 0000000000..594c8eac6a
--- /dev/null
+++ b/toolkit/components/protobuf/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(std::string *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(std::string *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, std::string::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 std::string &s, const std::string &oldsub,
+ const std::string &newsub, bool replace_all,
+ std::string *res) {
+ if (oldsub.empty()) {
+ res->append(s); // if empty, append the given string.
+ return;
+ }
+
+ std::string::size_type start_pos = 0;
+ std::string::size_type pos;
+ do {
+ pos = s.find(oldsub, start_pos);
+ if (pos == std::string::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.
+// ----------------------------------------------------------------------
+
+std::string StringReplace(const std::string &s, const std::string &oldsub,
+ const std::string &newsub, bool replace_all) {
+ std::string 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++ = std::string(start, p - start);
+ }
+ }
+ return;
+ }
+
+ std::string::size_type begin_index, end_index;
+ begin_index = full.find_first_not_of(delim);
+ while (begin_index != std::string::npos) {
+ end_index = full.find_first_of(delim, begin_index);
+ if (end_index == std::string::npos) {
+ *result++ = std::string(full.substr(begin_index));
+ return;
+ }
+ *result++ =
+ std::string(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<std::string> *result) {
+ std::back_insert_iterator<std::vector<std::string> > 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) {
+ std::string::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 == std::string::npos) {
+ *result++ = std::string(full.substr(begin_index));
+ return;
+ }
+ *result++ =
+ std::string(full.substr(begin_index, (end_index - begin_index)));
+ begin_index = end_index + 1;
+ }
+ *result++ = std::string(full.substr(begin_index));
+}
+
+void SplitStringAllowEmpty(StringPiece full, const char *delim,
+ std::vector<std::string> *result) {
+ std::back_insert_iterator<std::vector<std::string> > 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, std::string *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<std::string> &components, const char *delim,
+ std::string *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<std::string> *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 "
+ << "\\" << std::string(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: \\"
+ << std::string(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 \\"
+ << std::string(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: \\"
+ << std::string(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 std::string &src, std::string *dest) {
+ return UnescapeCEscapeString(src, dest, nullptr);
+}
+
+int UnescapeCEscapeString(const std::string &src, std::string *dest,
+ std::vector<std::string> *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;
+}
+
+std::string UnescapeCEscapeString(const std::string &src) {
+ std::unique_ptr<char[]> unescaped(new char[src.size() + 1]);
+ int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), nullptr);
+ return std::string(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_t>(*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_t>(*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, std::string *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;
+ }
+ }
+}
+
+std::string CEscape(const std::string &src) {
+ std::string dest;
+ CEscapeAndAppend(src, &dest);
+ return dest;
+}
+
+namespace strings {
+
+std::string Utf8SafeCEscape(const std::string &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 std::string(dest.get(), len);
+}
+
+std::string CHexEscape(const std::string &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 std::string(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_t 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 std::numeric_limits<int32_t>::min();
+ } else if (errno == ERANGE && result == LONG_MAX) {
+ return std::numeric_limits<int32_t>::max();
+ } else if (errno == 0 && result < std::numeric_limits<int32_t>::min()) {
+ errno = ERANGE;
+ return std::numeric_limits<int32_t>::min();
+ } else if (errno == 0 && result > std::numeric_limits<int32_t>::max()) {
+ errno = ERANGE;
+ return std::numeric_limits<int32_t>::max();
+ }
+ if (errno == 0)
+ errno = saved_errno;
+ return static_cast<int32_t>(result);
+}
+
+uint32_t 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 std::numeric_limits<uint32_t>::max();
+ } else if (errno == 0 && result > std::numeric_limits<uint32_t>::max()) {
+ errno = ERANGE;
+ return std::numeric_limits<uint32_t>::max();
+ }
+ if (errno == 0)
+ errno = saved_errno;
+ return static_cast<uint32_t>(result);
+}
+
+inline bool safe_parse_sign(std::string *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(std::string 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 std::string &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(std::string 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(std::string 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_t 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_t 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_t 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_t(value) & 0xf];
+#endif
+ value >>= 4;
+ }
+ return buffer;
+}
+
+char *FastHex64ToBuffer(uint64_t value, char* buffer) {
+ return InternalFastHexToBuffer(value, buffer, 16);
+}
+
+char *FastHex32ToBuffer(uint32_t 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_t u, char* buffer) {
+ uint32_t 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_t i, char* buffer) {
+ uint32_t u = 0;
+ if (i < 0) {
+ *buffer++ = '-';
+ u -= i;
+ } else {
+ u = i;
+ }
+ return FastUInt32ToBufferLeft(u, buffer);
+}
+
+char* FastUInt64ToBufferLeft(uint64_t u64, char* buffer) {
+ int digits;
+ const char *ASCII_digits = nullptr;
+
+ uint32_t u = static_cast<uint32_t>(u64);
+ if (u == u64) return FastUInt32ToBufferLeft(u, buffer);
+
+ uint64_t 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_t i, char* buffer) {
+ uint64_t 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
+// ----------------------------------------------------------------------
+
+std::string SimpleItoa(int i) {
+ char buffer[kFastToBufferSize];
+ return (sizeof(i) == 4) ?
+ FastInt32ToBuffer(i, buffer) :
+ FastInt64ToBuffer(i, buffer);
+}
+
+std::string SimpleItoa(unsigned int i) {
+ char buffer[kFastToBufferSize];
+ return std::string(buffer, (sizeof(i) == 4)
+ ? FastUInt32ToBufferLeft(i, buffer)
+ : FastUInt64ToBufferLeft(i, buffer));
+}
+
+std::string SimpleItoa(long i) {
+ char buffer[kFastToBufferSize];
+ return (sizeof(i) == 4) ?
+ FastInt32ToBuffer(i, buffer) :
+ FastInt64ToBuffer(i, buffer);
+}
+
+std::string SimpleItoa(unsigned long i) {
+ char buffer[kFastToBufferSize];
+ return std::string(buffer, (sizeof(i) == 4)
+ ? FastUInt32ToBufferLeft(i, buffer)
+ : FastUInt64ToBufferLeft(i, buffer));
+}
+
+std::string SimpleItoa(long long i) {
+ char buffer[kFastToBufferSize];
+ return (sizeof(i) == 4) ?
+ FastInt32ToBuffer(i, buffer) :
+ FastInt64ToBuffer(i, buffer);
+}
+
+std::string SimpleItoa(unsigned long long i) {
+ char buffer[kFastToBufferSize];
+ return std::string(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.
+// ----------------------------------------------------------------------
+
+std::string SimpleDtoa(double value) {
+ char buffer[kDoubleToBufferSize];
+ return DoubleToBuffer(value, buffer);
+}
+
+std::string 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 std::string &str, int32_t *value) {
+ return safe_int_internal(str, value);
+}
+
+bool safe_strtou32(const std::string &str, uint32_t *value) {
+ return safe_uint_internal(str, value);
+}
+
+bool safe_strto64(const std::string &str, int64_t *value) {
+ return safe_int_internal(str, value);
+}
+
+bool safe_strtou64(const std::string &str, uint64_t *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_t value = hex.value;
+ uint64_t 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_t mask = (static_cast<uint64_t>(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;
+}
+
+std::string StrCat(const AlphaNum &a, const AlphaNum &b) {
+ std::string 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;
+}
+
+std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) {
+ std::string 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;
+}
+
+std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+ const AlphaNum &d) {
+ std::string 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;
+}
+
+std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+ const AlphaNum &d, const AlphaNum &e) {
+ std::string 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;
+}
+
+std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+ const AlphaNum &d, const AlphaNum &e, const AlphaNum &f) {
+ std::string 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;
+}
+
+std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+ const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
+ const AlphaNum &g) {
+ std::string 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;
+}
+
+std::string 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) {
+ std::string 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;
+}
+
+std::string 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) {
+ std::string 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(std::string *result, const AlphaNum &a) {
+ GOOGLE_DCHECK_NO_OVERLAP(*result, a);
+ result->append(a.data(), a.size());
+}
+
+void StrAppend(std::string *result, const AlphaNum &a, const AlphaNum &b) {
+ GOOGLE_DCHECK_NO_OVERLAP(*result, a);
+ GOOGLE_DCHECK_NO_OVERLAP(*result, b);
+ std::string::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(std::string *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);
+ std::string::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(std::string *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);
+ std::string::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 std::string &substring,
+ const std::string &replacement, std::string *s) {
+ GOOGLE_CHECK(s != nullptr);
+ if (s->empty() || substring.empty())
+ return 0;
+ std::string tmp;
+ int num_replacements = 0;
+ int pos = 0;
+ for (StringPiece::size_type match_pos =
+ s->find(substring.data(), pos, substring.length());
+ match_pos != std::string::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, std::string *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, std::string *dest) {
+ return Base64UnescapeInternal(src.data(), src.size(), dest, kUnBase64);
+}
+
+bool WebSafeBase64Unescape(StringPiece src, std::string *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_t 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_t 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_t 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_t 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,
+ std::string *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, std::string *dest,
+ bool do_padding) {
+ Base64EscapeInternal(src, szsrc, dest, do_padding, kBase64Chars);
+}
+
+void WebSafeBase64Escape(const unsigned char *src, int szsrc, std::string *dest,
+ bool do_padding) {
+ Base64EscapeInternal(src, szsrc, dest, do_padding, kWebSafeBase64Chars);
+}
+
+void Base64Escape(StringPiece src, std::string *dest) {
+ Base64Escape(reinterpret_cast<const unsigned char*>(src.data()),
+ src.size(), dest, true);
+}
+
+void WebSafeBase64Escape(StringPiece src, std::string *dest) {
+ WebSafeBase64Escape(reinterpret_cast<const unsigned char*>(src.data()),
+ src.size(), dest, false);
+}
+
+void WebSafeBase64EscapeWithPadding(StringPiece src, std::string *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_t code_point, char* output) {
+ uint32_t 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_t*>(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 std::string &src, std::string *dst,
+ bool auto_end_last_line) {
+ if (dst->empty()) {
+ dst->append(src);
+ CleanStringLineEndings(dst, auto_end_last_line);
+ } else {
+ std::string tmp = src;
+ CleanStringLineEndings(&tmp, auto_end_last_line);
+ dst->append(tmp);
+ }
+}
+
+void CleanStringLineEndings(std::string *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) {
+ uint64_t 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;
+ }
+ }
+ std::string::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.
+std::string 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.
+ std::string 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.
+ std::string 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/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.h b/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.h
new file mode 100644
index 0000000000..9658abf908
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.h
@@ -0,0 +1,950 @@
+// 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 std::string StripPrefixString(const std::string& str,
+ const std::string& 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 std::string StripSuffixString(const std::string& str,
+ const std::string& 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(std::string* s, const char* remove,
+ char replacewith);
+
+PROTOBUF_EXPORT void StripWhitespace(std::string* 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(std::string* s) {
+ std::string::iterator end = s->end();
+ for (std::string::iterator i = s->begin(); i != end; ++i) {
+ // tolower() changes based on locale. We don't want this!
+ if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A';
+ }
+}
+
+inline void UpperString(std::string* s) {
+ std::string::iterator end = s->end();
+ for (std::string::iterator i = s->begin(); i != end; ++i) {
+ // toupper() changes based on locale. We don't want this!
+ if ('a' <= *i && *i <= 'z') *i += 'A' - 'a';
+ }
+}
+
+inline void ToUpper(std::string* s) { UpperString(s); }
+
+inline std::string ToUpper(const std::string& s) {
+ std::string 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 std::string StringReplace(const std::string& s,
+ const std::string& oldsub,
+ const std::string& 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<std::string>* 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<std::string>* result);
+
+// ----------------------------------------------------------------------
+// Split()
+// Split a string using a character delimiter.
+// ----------------------------------------------------------------------
+inline std::vector<std::string> Split(StringPiece full, const char* delim,
+ bool skip_empty = true) {
+ std::vector<std::string> 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<std::string>& components,
+ const char* delim, std::string* result);
+
+inline std::string JoinStrings(const std::vector<std::string>& components,
+ const char* delim) {
+ std::string 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<std::string>* 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 std::string& src,
+ std::string* dest);
+PROTOBUF_EXPORT int UnescapeCEscapeString(const std::string& src,
+ std::string* dest,
+ std::vector<std::string>* errors);
+PROTOBUF_EXPORT std::string UnescapeCEscapeString(const std::string& src);
+
+// ----------------------------------------------------------------------
+// CEscape()
+// Escapes 'src' using C-style escape sequences and returns the resulting
+// string.
+//
+// Escaped chars: \n, \r, \t, ", ', \, and !isprint().
+// ----------------------------------------------------------------------
+PROTOBUF_EXPORT std::string CEscape(const std::string& src);
+
+// ----------------------------------------------------------------------
+// CEscapeAndAppend()
+// Escapes 'src' using C-style escape sequences, and appends the escaped
+// string to 'dest'.
+// ----------------------------------------------------------------------
+PROTOBUF_EXPORT void CEscapeAndAppend(StringPiece src, std::string* dest);
+
+namespace strings {
+// Like CEscape() but does not escape bytes with the upper bit set.
+PROTOBUF_EXPORT std::string Utf8SafeCEscape(const std::string& src);
+
+// Like CEscape() but uses hex (\x) escapes instead of octals.
+PROTOBUF_EXPORT std::string CHexEscape(const std::string& 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_t strto32_adaptor(const char* nptr, char** endptr,
+ int base);
+PROTOBUF_EXPORT uint32_t strtou32_adaptor(const char* nptr, char** endptr,
+ int base);
+
+inline int32_t strto32(const char *nptr, char **endptr, int base) {
+ if (sizeof(int32_t) == sizeof(long))
+ return strtol(nptr, endptr, base);
+ else
+ return strto32_adaptor(nptr, endptr, base);
+}
+
+inline uint32_t strtou32(const char *nptr, char **endptr, int base) {
+ if (sizeof(uint32_t) == 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_t strto64(const char *nptr, char **endptr, int base) {
+ static_assert(sizeof(int64_t) == sizeof(long long),
+ "sizeof int64_t is not sizeof long long");
+ return strtoll(nptr, endptr, base);
+}
+
+inline uint64_t strtou64(const char *nptr, char **endptr, int base) {
+ static_assert(sizeof(uint64_t) == sizeof(unsigned long long),
+ "sizeof uint64_t is not sizeof unsigned 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 std::string& str, int32_t* value);
+PROTOBUF_EXPORT bool safe_strtou32(const std::string& str, uint32_t* value);
+inline bool safe_strto32(const char* str, int32_t* value) {
+ return safe_strto32(std::string(str), value);
+}
+inline bool safe_strto32(StringPiece str, int32_t* value) {
+ return safe_strto32(str.ToString(), value);
+}
+inline bool safe_strtou32(const char* str, uint32_t* value) {
+ return safe_strtou32(std::string(str), value);
+}
+inline bool safe_strtou32(StringPiece str, uint32_t* value) {
+ return safe_strtou32(str.ToString(), value);
+}
+
+PROTOBUF_EXPORT bool safe_strto64(const std::string& str, int64_t* value);
+PROTOBUF_EXPORT bool safe_strtou64(const std::string& str, uint64_t* value);
+inline bool safe_strto64(const char* str, int64_t* value) {
+ return safe_strto64(std::string(str), value);
+}
+inline bool safe_strto64(StringPiece str, int64_t* value) {
+ return safe_strto64(str.ToString(), value);
+}
+inline bool safe_strtou64(const char* str, uint64_t* value) {
+ return safe_strtou64(std::string(str), value);
+}
+inline bool safe_strtou64(StringPiece str, uint64_t* 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 std::string& str, float* value) {
+ return safe_strtof(str.c_str(), value);
+}
+inline bool safe_strtod(const std::string& 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_t i, char* buffer);
+PROTOBUF_EXPORT char* FastInt64ToBuffer(int64_t i, char* buffer);
+char* FastUInt32ToBuffer(uint32_t i, char* buffer); // inline below
+char* FastUInt64ToBuffer(uint64_t i, char* buffer); // inline below
+PROTOBUF_EXPORT char* FastHexToBuffer(int i, char* buffer);
+PROTOBUF_EXPORT char* FastHex64ToBuffer(uint64_t i, char* buffer);
+PROTOBUF_EXPORT char* FastHex32ToBuffer(uint32_t 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_t i, char* buffer);
+PROTOBUF_EXPORT char* FastUInt32ToBufferLeft(uint32_t i, char* buffer);
+PROTOBUF_EXPORT char* FastInt64ToBufferLeft(int64_t i, char* buffer);
+PROTOBUF_EXPORT char* FastUInt64ToBufferLeft(uint64_t i, char* buffer);
+
+// Just define these in terms of the above.
+inline char* FastUInt32ToBuffer(uint32_t i, char* buffer) {
+ FastUInt32ToBufferLeft(i, buffer);
+ return buffer;
+}
+inline char* FastUInt64ToBuffer(uint64_t i, char* buffer) {
+ FastUInt64ToBufferLeft(i, buffer);
+ return buffer;
+}
+
+inline std::string SimpleBtoa(bool value) { return value ? "true" : "false"; }
+
+// ----------------------------------------------------------------------
+// SimpleItoa()
+// Description: converts an integer to a string.
+//
+// Return value: string
+// ----------------------------------------------------------------------
+PROTOBUF_EXPORT std::string SimpleItoa(int i);
+PROTOBUF_EXPORT std::string SimpleItoa(unsigned int i);
+PROTOBUF_EXPORT std::string SimpleItoa(long i);
+PROTOBUF_EXPORT std::string SimpleItoa(unsigned long i);
+PROTOBUF_EXPORT std::string SimpleItoa(long long i);
+PROTOBUF_EXPORT std::string 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 std::string SimpleDtoa(double value);
+PROTOBUF_EXPORT std::string 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_t 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_t>(v)
+ : sizeof(v) == 2 ? static_cast<uint16_t>(v)
+ : sizeof(v) == 4 ? static_cast<uint32_t>(v)
+ : static_cast<uint64_t>(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 std::string& 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 std::string StrCat(const AlphaNum& a, const AlphaNum& b);
+PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
+ const AlphaNum& c);
+PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
+ const AlphaNum& c, const AlphaNum& d);
+PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
+ const AlphaNum& c, const AlphaNum& d,
+ const AlphaNum& e);
+PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
+ const AlphaNum& c, const AlphaNum& d,
+ const AlphaNum& e, const AlphaNum& f);
+PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
+ const AlphaNum& c, const AlphaNum& d,
+ const AlphaNum& e, const AlphaNum& f,
+ const AlphaNum& g);
+PROTOBUF_EXPORT std::string 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 std::string 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 std::string StrCat(const AlphaNum& a) {
+ return std::string(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(std::string* dest, const AlphaNum& a);
+PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a,
+ const AlphaNum& b);
+PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a,
+ const AlphaNum& b, const AlphaNum& c);
+PROTOBUF_EXPORT void StrAppend(std::string* 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,
+ std::string* result) {
+ for (Iterator it = start; it != end; ++it) {
+ if (it != start) {
+ result->append(delim);
+ }
+ StrAppend(result, *it);
+ }
+}
+
+template <typename Range>
+std::string Join(const Range& components, const char* delim) {
+ std::string result;
+ Join(components.begin(), components.end(), delim, &result);
+ return result;
+}
+
+// ----------------------------------------------------------------------
+// ToHex()
+// Return a lower-case hex string representation of the given integer.
+// ----------------------------------------------------------------------
+PROTOBUF_EXPORT std::string ToHex(uint64_t 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 std::string& substring,
+ const std::string& replacement,
+ std::string* 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, std::string* 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, std::string* 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, std::string* dest);
+// Encode src into dest web-safely without padding.
+PROTOBUF_EXPORT void WebSafeBase64Escape(StringPiece src, std::string* dest);
+// Encode src into dest web-safely with padding.
+PROTOBUF_EXPORT void WebSafeBase64EscapeWithPadding(StringPiece src,
+ std::string* dest);
+
+PROTOBUF_EXPORT void Base64Escape(const unsigned char* src, int szsrc,
+ std::string* dest, bool do_padding);
+PROTOBUF_EXPORT void WebSafeBase64Escape(const unsigned char* src, int szsrc,
+ std::string* dest, bool do_padding);
+
+inline bool IsValidCodePoint(uint32_t 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_t 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 std::string& src,
+ std::string* dst,
+ bool auto_end_last_line);
+
+// Same as above, but transforms the argument in place.
+PROTOBUF_EXPORT void CleanStringLineEndings(std::string* 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/toolkit/components/protobuf/src/google/protobuf/stubs/substitute.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/substitute.cc
new file mode 100644
index 0000000000..d301682ee3
--- /dev/null
+++ b/toolkit/components/protobuf/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;
+}
+
+std::string Substitute(const std::string& 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) {
+ std::string result;
+ SubstituteAndAppend(&result, format.c_str(), arg0, arg1, arg2, arg3, arg4,
+ arg5, arg6, arg7, arg8, arg9);
+ return result;
+}
+
+void SubstituteAndAppend(std::string* 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/toolkit/components/protobuf/src/google/protobuf/stubs/substitute.h b/toolkit/components/protobuf/src/google/protobuf/stubs/substitute.h
new file mode 100644
index 0000000000..0f851de096
--- /dev/null
+++ b/toolkit/components/protobuf/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 std::string& 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 std::string Substitute(
+ const std::string& 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(
+ std::string* 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/toolkit/components/protobuf/src/google/protobuf/stubs/template_util.h b/toolkit/components/protobuf/src/google/protobuf/stubs/template_util.h
new file mode 100644
index 0000000000..feef904bea
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/stubs/template_util.h
@@ -0,0 +1,138 @@
+// Copyright 2005 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.
+
+// ----
+// Author: lar@google.com (Laramie Leavitt)
+//
+// Template metaprogramming utility functions.
+//
+// This code is compiled directly on many platforms, including client
+// platforms like Windows, Mac, and embedded systems. Before making
+// any changes here, make sure that you're not breaking any platforms.
+//
+//
+// The names chosen here reflect those used in tr1 and the boost::mpl
+// library, there are similar operations used in the Loki library as
+// well. I prefer the boost names for 2 reasons:
+// 1. I think that portions of the Boost libraries are more likely to
+// be included in the c++ standard.
+// 2. It is not impossible that some of the boost libraries will be
+// included in our own build in the future.
+// Both of these outcomes means that we may be able to directly replace
+// some of these with boost equivalents.
+//
+#ifndef GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
+#define GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Types small_ and big_ are guaranteed such that sizeof(small_) <
+// sizeof(big_)
+typedef char small_;
+
+struct big_ {
+ char dummy[2];
+};
+
+// Identity metafunction.
+template <class T>
+struct identity_ {
+ typedef T type;
+};
+
+// integral_constant, defined in tr1, is a wrapper for an integer
+// value. We don't really need this generality; we could get away
+// with hardcoding the integer type to bool. We use the fully
+// general integer_constant for compatibility with tr1.
+
+template<class T, T v>
+struct integral_constant {
+ static const T value = v;
+ typedef T value_type;
+ typedef integral_constant<T, v> type;
+};
+
+template <class T, T v> const T integral_constant<T, v>::value;
+
+
+// Abbreviations: true_type and false_type are structs that represent boolean
+// true and false values. Also define the boost::mpl versions of those names,
+// true_ and false_.
+typedef integral_constant<bool, true> true_type;
+typedef integral_constant<bool, false> false_type;
+typedef true_type true_;
+typedef false_type false_;
+
+// if_ is a templatized conditional statement.
+// if_<cond, A, B> is a compile time evaluation of cond.
+// if_<>::type contains A if cond is true, B otherwise.
+template<bool cond, typename A, typename B>
+struct if_{
+ typedef A type;
+};
+
+template<typename A, typename B>
+struct if_<false, A, B> {
+ typedef B type;
+};
+
+
+// type_equals_ is a template type comparator, similar to Loki IsSameType.
+// type_equals_<A, B>::value is true iff "A" is the same type as "B".
+//
+// New code should prefer base::is_same, defined in base/type_traits.h.
+// It is functionally identical, but is_same is the standard spelling.
+template<typename A, typename B>
+struct type_equals_ : public false_ {
+};
+
+template<typename A>
+struct type_equals_<A, A> : public true_ {
+};
+
+// and_ is a template && operator.
+// and_<A, B>::value evaluates "A::value && B::value".
+template<typename A, typename B>
+struct and_ : public integral_constant<bool, (A::value && B::value)> {
+};
+
+// or_ is a template || operator.
+// or_<A, B>::value evaluates "A::value || B::value".
+template<typename A, typename B>
+struct or_ : public integral_constant<bool, (A::value || B::value)> {
+};
+
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/time.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/time.cc
new file mode 100644
index 0000000000..692cb82287
--- /dev/null
+++ b/toolkit/components/protobuf/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_t kSecondsPerMinute = 60;
+static const int64_t kSecondsPerHour = 3600;
+static const int64_t kSecondsPerDay = kSecondsPerHour * 24;
+static const int64_t kSecondsPer400Years =
+ kSecondsPerDay * (400 * 365 + 400 / 4 - 3);
+// Seconds from 0001-01-01T00:00:00 to 1970-01-01T:00:00:00
+static const int64_t kSecondsFromEraToEpoch = 62135596800LL;
+// The range of timestamp values we support.
+static const int64_t kMinTime = -62135596800LL; // 0001-01-01T00:00:00
+static const int64_t 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_t 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_t 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_t 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_t 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_t SecondsSinceCommonEra(const DateTime& time) {
+ int64_t 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.
+std::string FormatNanos(int32_t 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_t* 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_t* 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_t 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_t* seconds) {
+ if (!ValidateDateTime(time)) {
+ return false;
+ }
+ *seconds = SecondsSinceCommonEra(time) - kSecondsFromEraToEpoch;
+ return true;
+}
+
+void GetCurrentTime(int64_t* seconds, int32_t* nanos) {
+ // TODO(xiaofeng): Improve the accuracy of this implementation (or just
+ // remove this method from protobuf).
+ *seconds = time(nullptr);
+ *nanos = 0;
+}
+
+std::string FormatTime(int64_t seconds, int32_t nanos) {
+ DateTime time;
+ if (nanos < 0 || nanos > 999999999 || !SecondsToDateTime(seconds, &time)) {
+ return "InvalidTime";
+ }
+ std::string 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 std::string& value, int64_t* seconds, int32_t* 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_t offset;
+ if ((data = ParseTimezoneOffset(data, &offset)) == nullptr) {
+ return false;
+ }
+ *seconds -= offset;
+ } else if (*data == '-') {
+ ++data;
+ int64_t 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/toolkit/components/protobuf/src/google/protobuf/stubs/time.h b/toolkit/components/protobuf/src/google/protobuf/stubs/time.h
new file mode 100644
index 0000000000..8b6e56214f
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/stubs/time.h
@@ -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.
+#ifndef GOOGLE_PROTOBUF_STUBS_TIME_H_
+#define GOOGLE_PROTOBUF_STUBS_TIME_H_
+
+#include <cstdint>
+
+#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_t 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_t* seconds);
+
+void PROTOBUF_EXPORT GetCurrentTime(int64_t* seconds, int32_t* 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].
+std::string PROTOBUF_EXPORT FormatTime(int64_t seconds, int32_t 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 std::string& value, int64_t* seconds,
+ int32_t* nanos);
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_TIME_H_
diff --git a/toolkit/components/protobuf/src/google/protobuf/text_format.cc b/toolkit/components/protobuf/src/google/protobuf/text_format.cc
new file mode 100644
index 0000000000..19110499d7
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/text_format.cc
@@ -0,0 +1,2746 @@
+// 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 <utility>
+#include <vector>
+
+#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/stubs/strutil.h>
+#include <google/protobuf/any.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/io/strtod.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/map_util.h>
+#include <google/protobuf/stubs/stl_util.h>
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+namespace {
+
+inline bool IsHexNumber(const std::string& str) {
+ return (str.length() >= 2 && str[0] == '0' &&
+ (str[1] == 'x' || str[1] == 'X'));
+}
+
+inline bool IsOctNumber(const std::string& str) {
+ return (str.length() >= 2 && str[0] == '0' &&
+ (str[1] >= '0' && str[1] < '8'));
+}
+
+} // namespace
+
+namespace internal {
+const char kDebugStringSilentMarker[] = "";
+const char kDebugStringSilentMarkerForDetection[] = "\t ";
+
+// Controls insertion of kDebugStringSilentMarker.
+PROTOBUF_EXPORT std::atomic<bool> enable_debug_text_format_marker;
+} // namespace internal
+
+std::string Message::DebugString() const {
+ std::string 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;
+}
+
+std::string Message::ShortDebugString() const {
+ std::string 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;
+}
+
+std::string Message::Utf8DebugString() const {
+ std::string 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<int64_t>(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<int64_t>(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 std::string& 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 std::string& prefix,
+ const std::string& 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 bar: 2"
+ // where "baz" and "bar" 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_silent_marker_(false),
+ 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 std::string& 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 std::string& 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 int32_t kint32max = std::numeric_limits<int32_t>::max();
+ static constexpr uint32_t kuint32max = std::numeric_limits<uint32_t>::max();
+ static constexpr int64_t kint64min = std::numeric_limits<int64_t>::min();
+ static constexpr int64_t kint64max = std::numeric_limits<int64_t>::max();
+ static constexpr uint64_t kuint64max = std::numeric_limits<uint64_t>::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 std::string& 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 std::string& 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 std::string 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(std::string* 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();
+
+ std::string 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("[")) {
+ std::string full_type_name, prefix;
+ DO(ConsumeAnyTypeUrl(&full_type_name, &prefix));
+ std::string prefix_and_full_type_name =
+ StrCat(prefix, full_type_name);
+ DO(ConsumeBeforeWhitespace("]"));
+ TryConsumeWhitespace();
+ // ':' is optional between message labels and values.
+ if (TryConsumeBeforeWhitespace(":")) {
+ TryConsumeWhitespace();
+ }
+ std::string 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,
+ std::move(prefix_and_full_type_name));
+ reflection->SetString(message, any_value_field,
+ std::move(serialized_value));
+ return true;
+ }
+ if (TryConsume("[")) {
+ // Extension.
+ DO(ConsumeFullTypeName(&field_name));
+ DO(ConsumeBeforeWhitespace("]"));
+ TryConsumeWhitespace();
+
+ 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();
+
+ int32_t 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) {
+ std::string 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_) {
+ std::string 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.
+ if (TryConsumeBeforeWhitespace(":")) {
+ TryConsumeWhitespace();
+ if (!LookingAt("{") && !LookingAt("<")) {
+ return SkipFieldValue();
+ }
+ }
+ return SkipFieldMessage();
+ }
+
+ 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(":");
+ if (consumed_semicolon) {
+ TryConsumeWhitespace();
+ }
+ if (consumed_semicolon && field->options().weak() &&
+ LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ // we are getting a bytes string for a weak field.
+ std::string 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();
+ }
+
+ 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() {
+ std::string field_name;
+ if (TryConsume("[")) {
+ // Extension name or type URL.
+ DO(ConsumeTypeUrlOrFullTypeName(&field_name));
+ DO(ConsumeBeforeWhitespace("]"));
+ } else {
+ DO(ConsumeIdentifierBeforeWhitespace(&field_name));
+ }
+ TryConsumeWhitespace();
+
+ // 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();
+ 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);
+ }
+
+ std::string 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;
+ }
+
+ std::string 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: {
+ int64_t value;
+ DO(ConsumeSignedInteger(&value, kint32max));
+ SET_FIELD(Int32, static_cast<int32_t>(value));
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_UINT32: {
+ uint64_t value;
+ DO(ConsumeUnsignedInteger(&value, kuint32max));
+ SET_FIELD(UInt32, static_cast<uint32_t>(value));
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_INT64: {
+ int64_t value;
+ DO(ConsumeSignedInteger(&value, kint64max));
+ SET_FIELD(Int64, value);
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_UINT64: {
+ uint64_t 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: {
+ std::string value;
+ DO(ConsumeString(&value));
+ SET_FIELD(String, std::move(value));
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_BOOL: {
+ if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ uint64_t value;
+ DO(ConsumeUnsignedInteger(&value, 1));
+ SET_FIELD(Bool, value);
+ } else {
+ std::string 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: {
+ std::string value;
+ int64_t 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)) {
+ std::string 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)) {
+ std::string 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 std::string& 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(std::string* 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(std::string* 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(std::string* name) {
+ DO(ConsumeIdentifier(name));
+ while (TryConsume(".")) {
+ std::string part;
+ DO(ConsumeIdentifier(&part));
+ *name += ".";
+ *name += part;
+ }
+ return true;
+ }
+
+ bool ConsumeTypeUrlOrFullTypeName(std::string* name) {
+ DO(ConsumeIdentifier(name));
+ while (true) {
+ std::string connector;
+ if (TryConsume(".")) {
+ connector = ".";
+ } else if (TryConsume("/")) {
+ connector = "/";
+ } else {
+ break;
+ }
+ std::string part;
+ DO(ConsumeIdentifier(&part));
+ *name += connector;
+ *name += part;
+ }
+ 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(std::string* 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 uint64_t and saves its value in the value parameter.
+ // Returns false if the token is not of type INTEGER.
+ bool ConsumeUnsignedInteger(uint64_t* value, uint64_t 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 int64_t 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(int64_t* value, uint64_t max_value) {
+ bool negative = false;
+
+ if (TryConsume("-")) {
+ negative = true;
+ // Two's complement always allows one more negative integer than
+ // positive.
+ ++max_value;
+ }
+
+ uint64_t unsigned_value;
+
+ DO(ConsumeUnsignedInteger(&unsigned_value, max_value));
+
+ if (negative) {
+ if ((static_cast<uint64_t>(kint64max) + 1) == unsigned_value) {
+ *value = kint64min;
+ } else {
+ *value = -static_cast<int64_t>(unsigned_value);
+ }
+ } else {
+ *value = static_cast<int64_t>(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, uint64_t max_value) {
+ if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ ReportError("Expected integer, got: " + tokenizer_.current().text);
+ return false;
+ }
+
+ const std::string& text = tokenizer_.current().text;
+ if (IsHexNumber(text) || IsOctNumber(text)) {
+ ReportError("Expect a decimal number, got: " + text);
+ return false;
+ }
+
+ uint64_t 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)) {
+ std::string 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(std::string* full_type_name, std::string* 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(".")) {
+ std::string 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,
+ std::string* 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());
+ std::string 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 std::string& value) {
+ const std::string& 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 std::string& 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 std::string& 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 std::string& 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() {
+ had_silent_marker_ = false;
+ if (LookingAtType(io::Tokenizer::TYPE_WHITESPACE)) {
+ if (tokenizer_.current().text ==
+ StrCat(" ", internal::kDebugStringSilentMarkerForDetection)) {
+ had_silent_marker_ = true;
+ }
+ 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 std::string& message) override {
+ parser_->ReportError(line, column, message);
+ }
+
+ void AddWarning(int line, int column, const std::string& 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_silent_marker_;
+ 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() override {
+ // Only BackUp() if we're sure we've successfully called Next() at least
+ // once.
+ if (!failed_) {
+ 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(internal::kDebugStringSilentMarker);
+ }
+ }
+
+ void PrintMaybeWithMarker(StringPiece text_head,
+ StringPiece text_tail) {
+ Print(text_head.data(), text_head.size());
+ if (ConsumeInsertSilentMarker()) {
+ PrintLiteral(internal::kDebugStringSilentMarker);
+ }
+ 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<int64_t>(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 std::string& val,
+ TextFormat::BaseTextGenerator* generator) const override {
+ generator->PrintLiteral("\"");
+ generator->PrintString(strings::Utf8SafeCEscape(val));
+ generator->PrintLiteral("\"");
+ }
+ void PrintBytes(const std::string& 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 std::string& 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 std::string& prefix,
+ const std::string& 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<int64_t>(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<std::string> 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 std::string& 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
+ std::string Consume() && { return std::move(output_); }
+#else // !LANG_CXX11
+ const std::string& Get() { return output_; }
+#endif // LANG_CXX11
+
+ private:
+ std::string 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
+
+std::string TextFormat::FieldValuePrinter::PrintBool(bool val) const {
+ FORWARD_IMPL(PrintBool, val);
+}
+std::string TextFormat::FieldValuePrinter::PrintInt32(int32_t val) const {
+ FORWARD_IMPL(PrintInt32, val);
+}
+std::string TextFormat::FieldValuePrinter::PrintUInt32(uint32_t val) const {
+ FORWARD_IMPL(PrintUInt32, val);
+}
+std::string TextFormat::FieldValuePrinter::PrintInt64(int64_t val) const {
+ FORWARD_IMPL(PrintInt64, val);
+}
+std::string TextFormat::FieldValuePrinter::PrintUInt64(uint64_t val) const {
+ FORWARD_IMPL(PrintUInt64, val);
+}
+std::string TextFormat::FieldValuePrinter::PrintFloat(float val) const {
+ FORWARD_IMPL(PrintFloat, val);
+}
+std::string TextFormat::FieldValuePrinter::PrintDouble(double val) const {
+ FORWARD_IMPL(PrintDouble, val);
+}
+std::string TextFormat::FieldValuePrinter::PrintString(
+ const std::string& val) const {
+ FORWARD_IMPL(PrintString, val);
+}
+std::string TextFormat::FieldValuePrinter::PrintBytes(
+ const std::string& val) const {
+ return PrintString(val);
+}
+std::string TextFormat::FieldValuePrinter::PrintEnum(
+ int32_t val, const std::string& name) const {
+ FORWARD_IMPL(PrintEnum, val, name);
+}
+std::string TextFormat::FieldValuePrinter::PrintFieldName(
+ const Message& message, const Reflection* reflection,
+ const FieldDescriptor* field) const {
+ FORWARD_IMPL(PrintFieldName, message, reflection, field);
+}
+std::string 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);
+}
+std::string 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(
+ int32_t val, BaseTextGenerator* generator) const {
+ generator->PrintString(StrCat(val));
+}
+void TextFormat::FastFieldValuePrinter::PrintUInt32(
+ uint32_t val, BaseTextGenerator* generator) const {
+ generator->PrintString(StrCat(val));
+}
+void TextFormat::FastFieldValuePrinter::PrintInt64(
+ int64_t val, BaseTextGenerator* generator) const {
+ generator->PrintString(StrCat(val));
+}
+void TextFormat::FastFieldValuePrinter::PrintUInt64(
+ uint64_t 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(
+ int32_t /*val*/, const std::string& name,
+ BaseTextGenerator* generator) const {
+ generator->PrintString(name);
+}
+
+void TextFormat::FastFieldValuePrinter::PrintString(
+ const std::string& val, BaseTextGenerator* generator) const {
+ generator->PrintLiteral("\"");
+ generator->PrintString(CEscape(val));
+ generator->PrintLiteral("\"");
+}
+void TextFormat::FastFieldValuePrinter::PrintBytes(
+ const std::string& 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(int32_t val,
+ TextFormat::BaseTextGenerator* generator) const override {
+ generator->PrintString(delegate_->PrintInt32(val));
+ }
+ void PrintUInt32(uint32_t val,
+ TextFormat::BaseTextGenerator* generator) const override {
+ generator->PrintString(delegate_->PrintUInt32(val));
+ }
+ void PrintInt64(int64_t val,
+ TextFormat::BaseTextGenerator* generator) const override {
+ generator->PrintString(delegate_->PrintInt64(val));
+ }
+ void PrintUInt64(uint64_t 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 std::string& val,
+ TextFormat::BaseTextGenerator* generator) const override {
+ generator->PrintString(delegate_->PrintString(val));
+ }
+ void PrintBytes(const std::string& val,
+ TextFormat::BaseTextGenerator* generator) const override {
+ generator->PrintString(delegate_->PrintBytes(val));
+ }
+ void PrintEnum(int32_t val, const std::string& 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,
+ std::string* 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, std::string* 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 std::string& type_url = reflection->GetString(message, type_url_field);
+ std::string url_prefix;
+ std::string 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());
+ std::string 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;
+ {
+ std::string 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,
+ std::string* 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: {
+ int32_t first = reflection->GetInt32(*a, field_);
+ int32_t second = reflection->GetInt32(*b, field_);
+ return first < second;
+ }
+ case FieldDescriptor::CPPTYPE_INT64: {
+ int64_t first = reflection->GetInt64(*a, field_);
+ int64_t second = reflection->GetInt64(*b, field_);
+ return first < second;
+ }
+ case FieldDescriptor::CPPTYPE_UINT32: {
+ uint32_t first = reflection->GetUInt32(*a, field_);
+ uint32_t second = reflection->GetUInt32(*b, field_);
+ return first < second;
+ }
+ case FieldDescriptor::CPPTYPE_UINT64: {
+ uint64_t first = reflection->GetUInt64(*a, field_);
+ uint64_t second = reflection->GetUInt64(*b, field_);
+ return first < second;
+ }
+ case FieldDescriptor::CPPTYPE_STRING: {
+ std::string first = reflection->GetString(*a, field_);
+ std::string 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: {
+ std::string scratch;
+ const std::string& value =
+ field->is_repeated()
+ ? reflection->GetRepeatedStringReference(message, field, index,
+ &scratch)
+ : reflection->GetStringReference(message, field, &scratch);
+ const std::string* value_to_print = &value;
+ std::string 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,
+ std::string* output) {
+ return Printer().PrintToString(message, output);
+}
+
+/* static */ bool TextFormat::PrintUnknownFieldsToString(
+ const UnknownFieldSet& unknown_fields, std::string* output) {
+ return Printer().PrintUnknownFieldsToString(unknown_fields, output);
+}
+
+/* static */ void TextFormat::PrintFieldValueToString(
+ const Message& message, const FieldDescriptor* field, int index,
+ std::string* output) {
+ return Printer().PrintFieldValueToString(message, field, index, output);
+}
+
+/* static */ bool TextFormat::ParseFieldValueFromString(
+ const std::string& 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);
+ std::string 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 std::string& 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/toolkit/components/protobuf/src/google/protobuf/text_format.h b/toolkit/components/protobuf/src/google/protobuf/text_format.h
new file mode 100644
index 0000000000..e10bef7ddf
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/text_format.h
@@ -0,0 +1,693 @@
+// 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/port.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/message_lite.h>
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+namespace google {
+namespace protobuf {
+
+namespace internal {
+PROTOBUF_EXPORT extern const char kDebugStringSilentMarker[1];
+PROTOBUF_EXPORT extern const char kDebugStringSilentMarkerForDetection[3];
+} // namespace internal
+
+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, std::string* output);
+
+ // Like PrintUnknownFields(), but outputs directly to a string. Returns
+ // false if printing fails.
+ static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
+ std::string* 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,
+ std::string* 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 std::string& 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(int32_t val, BaseTextGenerator* generator) const;
+ virtual void PrintUInt32(uint32_t val, BaseTextGenerator* generator) const;
+ virtual void PrintInt64(int64_t val, BaseTextGenerator* generator) const;
+ virtual void PrintUInt64(uint64_t val, BaseTextGenerator* generator) const;
+ virtual void PrintFloat(float val, BaseTextGenerator* generator) const;
+ virtual void PrintDouble(double val, BaseTextGenerator* generator) const;
+ virtual void PrintString(const std::string& val,
+ BaseTextGenerator* generator) const;
+ virtual void PrintBytes(const std::string& val,
+ BaseTextGenerator* generator) const;
+ virtual void PrintEnum(int32_t val, const std::string& 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 std::string PrintBool(bool val) const;
+ virtual std::string PrintInt32(int32_t val) const;
+ virtual std::string PrintUInt32(uint32_t val) const;
+ virtual std::string PrintInt64(int64_t val) const;
+ virtual std::string PrintUInt64(uint64_t val) const;
+ virtual std::string PrintFloat(float val) const;
+ virtual std::string PrintDouble(double val) const;
+ virtual std::string PrintString(const std::string& val) const;
+ virtual std::string PrintBytes(const std::string& val) const;
+ virtual std::string PrintEnum(int32_t val, const std::string& name) const;
+ virtual std::string PrintFieldName(const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field) const;
+ virtual std::string PrintMessageStart(const Message& message,
+ int field_index, int field_count,
+ bool single_line_mode) const;
+ virtual std::string 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 std::string& 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 std::string& prefix,
+ const std::string& 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, std::string* output) const;
+ // Like TextFormat::PrintUnknownFieldsToString
+ bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
+ std::string* output) const;
+ // Like TextFormat::PrintFieldValueToString
+ void PrintFieldValueToString(const Message& message,
+ const FieldDescriptor* field, int index,
+ std::string* 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 int64_t 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 std::string Message::DebugString() const;
+ friend std::string Message::ShortDebugString() const;
+ friend std::string 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_;
+ int64_t 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
+ // serialization 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 common use for this function is parsing handwritten strings in test
+ // code.
+ //
+ // 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 std::string& 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 std::string& 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/toolkit/components/protobuf/src/google/protobuf/timestamp.pb.cc b/toolkit/components/protobuf/src/google/protobuf/timestamp.pb.cc
new file mode 100644
index 0000000000..728a004389
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/timestamp.pb.cc
@@ -0,0 +1,307 @@
+// 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
+
+namespace _pb = ::PROTOBUF_NAMESPACE_ID;
+namespace _pbi = _pb::internal;
+
+PROTOBUF_NAMESPACE_OPEN
+PROTOBUF_CONSTEXPR Timestamp::Timestamp(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.seconds_)*/int64_t{0}
+ , /*decltype(_impl_.nanos_)*/0
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct TimestampDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR TimestampDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~TimestampDefaultTypeInternal() {}
+ union {
+ Timestamp _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 TimestampDefaultTypeInternal _Timestamp_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto[1];
+static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr;
+static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr;
+
+const uint32_t 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, _impl_.seconds_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Timestamp, _impl_.nanos_),
+};
+static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Timestamp)},
+};
+
+static const ::_pb::Message* const file_default_instances[] = {
+ &::PROTOBUF_NAMESPACE_ID::_Timestamp_default_instance_._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 ::_pbi::once_flag descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_once;
+const ::_pbi::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 ::_pbi::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_PRIORITY2 static ::_pbi::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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Timestamp)
+}
+Timestamp::Timestamp(const Timestamp& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Timestamp* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.seconds_){}
+ , decltype(_impl_.nanos_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ ::memcpy(&_impl_.seconds_, &from._impl_.seconds_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.nanos_) -
+ reinterpret_cast<char*>(&_impl_.seconds_)) + sizeof(_impl_.nanos_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Timestamp)
+}
+
+inline void Timestamp::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.seconds_){int64_t{0}}
+ , decltype(_impl_.nanos_){0}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+Timestamp::~Timestamp() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Timestamp)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Timestamp::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void Timestamp::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void Timestamp::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Timestamp)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ ::memset(&_impl_.seconds_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.nanos_) -
+ reinterpret_cast<char*>(&_impl_.seconds_)) + sizeof(_impl_.nanos_));
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Timestamp::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // int64 seconds = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _impl_.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)) {
+ _impl_.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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // int64 seconds = 1;
+ if (this->_internal_seconds() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteInt64ToArray(1, this->_internal_seconds(), target);
+ }
+
+ // int32 nanos = 2;
+ if (this->_internal_nanos() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_nanos(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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 += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_seconds());
+ }
+
+ // int32 nanos = 2;
+ if (this->_internal_nanos() != 0) {
+ total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_nanos());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Timestamp::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Timestamp::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Timestamp::GetClassData() const { return &_class_data_; }
+
+
+void Timestamp::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Timestamp*>(&to_msg);
+ auto& from = static_cast<const Timestamp&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Timestamp)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_seconds() != 0) {
+ _this->_internal_set_seconds(from._internal_seconds());
+ }
+ if (from._internal_nanos() != 0) {
+ _this->_internal_set_nanos(from._internal_nanos());
+ }
+ _this->_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, _impl_.nanos_)
+ + sizeof(Timestamp::_impl_.nanos_)
+ - PROTOBUF_FIELD_OFFSET(Timestamp, _impl_.seconds_)>(
+ reinterpret_cast<char*>(&_impl_.seconds_),
+ reinterpret_cast<char*>(&other->_impl_.seconds_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Timestamp::GetMetadata() const {
+ return ::_pbi::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/toolkit/components/protobuf/src/google/protobuf/timestamp.pb.h b/toolkit/components/protobuf/src/google/protobuf/timestamp.pb.h
new file mode 100644
index 0000000000..6633822791
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/timestamp.pb.h
@@ -0,0 +1,278 @@
+// 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 < 3021000
+#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 3021006 < 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_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 uint32_t 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 PROTOBUF_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) {
+ Timestamp::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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();
+ int64_t seconds() const;
+ void set_seconds(int64_t value);
+ private:
+ int64_t _internal_seconds() const;
+ void _internal_set_seconds(int64_t value);
+ public:
+
+ // int32 nanos = 2;
+ void clear_nanos();
+ int32_t nanos() const;
+ void set_nanos(int32_t value);
+ private:
+ int32_t _internal_nanos() const;
+ void _internal_set_nanos(int32_t 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_;
+ struct Impl_ {
+ int64_t seconds_;
+ int32_t nanos_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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() {
+ _impl_.seconds_ = int64_t{0};
+}
+inline int64_t Timestamp::_internal_seconds() const {
+ return _impl_.seconds_;
+}
+inline int64_t Timestamp::seconds() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Timestamp.seconds)
+ return _internal_seconds();
+}
+inline void Timestamp::_internal_set_seconds(int64_t value) {
+
+ _impl_.seconds_ = value;
+}
+inline void Timestamp::set_seconds(int64_t value) {
+ _internal_set_seconds(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Timestamp.seconds)
+}
+
+// int32 nanos = 2;
+inline void Timestamp::clear_nanos() {
+ _impl_.nanos_ = 0;
+}
+inline int32_t Timestamp::_internal_nanos() const {
+ return _impl_.nanos_;
+}
+inline int32_t Timestamp::nanos() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Timestamp.nanos)
+ return _internal_nanos();
+}
+inline void Timestamp::_internal_set_nanos(int32_t value) {
+
+ _impl_.nanos_ = value;
+}
+inline void Timestamp::set_nanos(int32_t 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/toolkit/components/protobuf/src/google/protobuf/timestamp.proto b/toolkit/components/protobuf/src/google/protobuf/timestamp.proto
new file mode 100644
index 0000000000..3b2df6d911
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/type.pb.cc b/toolkit/components/protobuf/src/google/protobuf/type.pb.cc
new file mode 100644
index 0000000000..e29bbb83a1
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/type.pb.cc
@@ -0,0 +1,2157 @@
+// 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
+
+namespace _pb = ::PROTOBUF_NAMESPACE_ID;
+namespace _pbi = _pb::internal;
+
+PROTOBUF_NAMESPACE_OPEN
+PROTOBUF_CONSTEXPR Type::Type(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.fields_)*/{}
+ , /*decltype(_impl_.oneofs_)*/{}
+ , /*decltype(_impl_.options_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.source_context_)*/nullptr
+ , /*decltype(_impl_.syntax_)*/0
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct TypeDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR TypeDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~TypeDefaultTypeInternal() {}
+ union {
+ Type _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 TypeDefaultTypeInternal _Type_default_instance_;
+PROTOBUF_CONSTEXPR Field::Field(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.options_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.type_url_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.json_name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.default_value_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.kind_)*/0
+ , /*decltype(_impl_.cardinality_)*/0
+ , /*decltype(_impl_.number_)*/0
+ , /*decltype(_impl_.oneof_index_)*/0
+ , /*decltype(_impl_.packed_)*/false
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct FieldDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR FieldDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~FieldDefaultTypeInternal() {}
+ union {
+ Field _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FieldDefaultTypeInternal _Field_default_instance_;
+PROTOBUF_CONSTEXPR Enum::Enum(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.enumvalue_)*/{}
+ , /*decltype(_impl_.options_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.source_context_)*/nullptr
+ , /*decltype(_impl_.syntax_)*/0
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct EnumDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR EnumDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~EnumDefaultTypeInternal() {}
+ union {
+ Enum _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumDefaultTypeInternal _Enum_default_instance_;
+PROTOBUF_CONSTEXPR EnumValue::EnumValue(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.options_)*/{}
+ , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.number_)*/0
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct EnumValueDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR EnumValueDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~EnumValueDefaultTypeInternal() {}
+ union {
+ EnumValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumValueDefaultTypeInternal _EnumValue_default_instance_;
+PROTOBUF_CONSTEXPR Option::Option(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_.value_)*/nullptr
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct OptionDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR OptionDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~OptionDefaultTypeInternal() {}
+ union {
+ Option _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 OptionDefaultTypeInternal _Option_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2ftype_2eproto[5];
+static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[3];
+static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ftype_2eproto = nullptr;
+
+const uint32_t 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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, _impl_.fields_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, _impl_.oneofs_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, _impl_.options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, _impl_.source_context_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, _impl_.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, _impl_.kind_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, _impl_.cardinality_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, _impl_.number_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, _impl_.type_url_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, _impl_.oneof_index_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, _impl_.packed_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, _impl_.options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, _impl_.json_name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, _impl_.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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, _impl_.enumvalue_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, _impl_.options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, _impl_.source_context_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, _impl_.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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValue, _impl_.number_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValue, _impl_.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, _impl_.name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Option, _impl_.value_),
+};
+static const ::_pbi::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 const ::_pb::Message* const file_default_instances[] = {
+ &::PROTOBUF_NAMESPACE_ID::_Type_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_Field_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_Enum_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_EnumValue_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_Option_default_instance_._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 ::_pbi::DescriptorTable* const descriptor_table_google_2fprotobuf_2ftype_2eproto_deps[2] = {
+ &::descriptor_table_google_2fprotobuf_2fany_2eproto,
+ &::descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto,
+};
+static ::_pbi::once_flag descriptor_table_google_2fprotobuf_2ftype_2eproto_once;
+const ::_pbi::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 ::_pbi::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_PRIORITY2 static ::_pbi::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->_impl_.source_context_;
+}
+void Type::clear_source_context() {
+ if (GetArenaForAllocation() == nullptr && _impl_.source_context_ != nullptr) {
+ delete _impl_.source_context_;
+ }
+ _impl_.source_context_ = nullptr;
+}
+Type::Type(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Type)
+}
+Type::Type(const Type& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Type* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.fields_){from._impl_.fields_}
+ , decltype(_impl_.oneofs_){from._impl_.oneofs_}
+ , decltype(_impl_.options_){from._impl_.options_}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.source_context_){nullptr}
+ , decltype(_impl_.syntax_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ if (from._internal_has_source_context()) {
+ _this->_impl_.source_context_ = new ::PROTOBUF_NAMESPACE_ID::SourceContext(*from._impl_.source_context_);
+ }
+ _this->_impl_.syntax_ = from._impl_.syntax_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Type)
+}
+
+inline void Type::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.fields_){arena}
+ , decltype(_impl_.oneofs_){arena}
+ , decltype(_impl_.options_){arena}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.source_context_){nullptr}
+ , decltype(_impl_.syntax_){0}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+Type::~Type() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Type)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Type::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.fields_.~RepeatedPtrField();
+ _impl_.oneofs_.~RepeatedPtrField();
+ _impl_.options_.~RepeatedPtrField();
+ _impl_.name_.Destroy();
+ if (this != internal_default_instance()) delete _impl_.source_context_;
+}
+
+void Type::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void Type::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Type)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.fields_.Clear();
+ _impl_.oneofs_.Clear();
+ _impl_.options_.Clear();
+ _impl_.name_.ClearToEmpty();
+ if (GetArenaForAllocation() == nullptr && _impl_.source_context_ != nullptr) {
+ delete _impl_.source_context_;
+ }
+ _impl_.source_context_ = nullptr;
+ _impl_.syntax_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Type::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Type.name"));
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Type.oneofs"));
+ 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)) {
+ uint64_t 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)
+ uint32_t 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 i = 0,
+ n = static_cast<unsigned>(this->_internal_fields_size()); i < n; i++) {
+ const auto& repfield = this->_internal_fields(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, repfield, repfield.GetCachedSize(), 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 i = 0,
+ n = static_cast<unsigned>(this->_internal_options_size()); i < n; i++) {
+ const auto& repfield = this->_internal_options(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(4, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // .google.protobuf.SourceContext source_context = 5;
+ if (this->_internal_has_source_context()) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(5, _Internal::source_context(this),
+ _Internal::source_context(this).GetCachedSize(), target, stream);
+ }
+
+ // .google.protobuf.Syntax syntax = 6;
+ if (this->_internal_syntax() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteEnumToArray(
+ 6, this->_internal_syntax(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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->_impl_.fields_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated string oneofs = 3;
+ total_size += 1 *
+ ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(_impl_.oneofs_.size());
+ for (int i = 0, n = _impl_.oneofs_.size(); i < n; i++) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ _impl_.oneofs_.Get(i));
+ }
+
+ // repeated .google.protobuf.Option options = 4;
+ total_size += 1UL * this->_internal_options_size();
+ for (const auto& msg : this->_impl_.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(
+ *_impl_.source_context_);
+ }
+
+ // .google.protobuf.Syntax syntax = 6;
+ if (this->_internal_syntax() != 0) {
+ total_size += 1 +
+ ::_pbi::WireFormatLite::EnumSize(this->_internal_syntax());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Type::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Type::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Type::GetClassData() const { return &_class_data_; }
+
+
+void Type::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Type*>(&to_msg);
+ auto& from = static_cast<const Type&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Type)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.fields_.MergeFrom(from._impl_.fields_);
+ _this->_impl_.oneofs_.MergeFrom(from._impl_.oneofs_);
+ _this->_impl_.options_.MergeFrom(from._impl_.options_);
+ if (!from._internal_name().empty()) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (from._internal_has_source_context()) {
+ _this->_internal_mutable_source_context()->::PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(
+ from._internal_source_context());
+ }
+ if (from._internal_syntax() != 0) {
+ _this->_internal_set_syntax(from._internal_syntax());
+ }
+ _this->_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_);
+ _impl_.fields_.InternalSwap(&other->_impl_.fields_);
+ _impl_.oneofs_.InternalSwap(&other->_impl_.oneofs_);
+ _impl_.options_.InternalSwap(&other->_impl_.options_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(Type, _impl_.syntax_)
+ + sizeof(Type::_impl_.syntax_)
+ - PROTOBUF_FIELD_OFFSET(Type, _impl_.source_context_)>(
+ reinterpret_cast<char*>(&_impl_.source_context_),
+ reinterpret_cast<char*>(&other->_impl_.source_context_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Type::GetMetadata() const {
+ return ::_pbi::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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Field)
+}
+Field::Field(const Field& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Field* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.options_){from._impl_.options_}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.type_url_){}
+ , decltype(_impl_.json_name_){}
+ , decltype(_impl_.default_value_){}
+ , decltype(_impl_.kind_){}
+ , decltype(_impl_.cardinality_){}
+ , decltype(_impl_.number_){}
+ , decltype(_impl_.oneof_index_){}
+ , decltype(_impl_.packed_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.type_url_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.type_url_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_type_url().empty()) {
+ _this->_impl_.type_url_.Set(from._internal_type_url(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.json_name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.json_name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_json_name().empty()) {
+ _this->_impl_.json_name_.Set(from._internal_json_name(),
+ _this->GetArenaForAllocation());
+ }
+ _impl_.default_value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.default_value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_default_value().empty()) {
+ _this->_impl_.default_value_.Set(from._internal_default_value(),
+ _this->GetArenaForAllocation());
+ }
+ ::memcpy(&_impl_.kind_, &from._impl_.kind_,
+ static_cast<size_t>(reinterpret_cast<char*>(&_impl_.packed_) -
+ reinterpret_cast<char*>(&_impl_.kind_)) + sizeof(_impl_.packed_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Field)
+}
+
+inline void Field::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.options_){arena}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.type_url_){}
+ , decltype(_impl_.json_name_){}
+ , decltype(_impl_.default_value_){}
+ , decltype(_impl_.kind_){0}
+ , decltype(_impl_.cardinality_){0}
+ , decltype(_impl_.number_){0}
+ , decltype(_impl_.oneof_index_){0}
+ , decltype(_impl_.packed_){false}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.type_url_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.type_url_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.json_name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.json_name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.default_value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.default_value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+Field::~Field() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Field)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Field::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.options_.~RepeatedPtrField();
+ _impl_.name_.Destroy();
+ _impl_.type_url_.Destroy();
+ _impl_.json_name_.Destroy();
+ _impl_.default_value_.Destroy();
+}
+
+void Field::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void Field::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Field)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.options_.Clear();
+ _impl_.name_.ClearToEmpty();
+ _impl_.type_url_.ClearToEmpty();
+ _impl_.json_name_.ClearToEmpty();
+ _impl_.default_value_.ClearToEmpty();
+ ::memset(&_impl_.kind_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&_impl_.packed_) -
+ reinterpret_cast<char*>(&_impl_.kind_)) + sizeof(_impl_.packed_));
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Field::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // .google.protobuf.Field.Kind kind = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ uint64_t 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)) {
+ uint64_t 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)) {
+ _impl_.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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Field.name"));
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Field.type_url"));
+ } else
+ goto handle_unusual;
+ continue;
+ // int32 oneof_index = 7;
+ case 7:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 56)) {
+ _impl_.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)) {
+ _impl_.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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Field.json_name"));
+ } 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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Field.default_value"));
+ } 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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // .google.protobuf.Field.Kind kind = 1;
+ if (this->_internal_kind() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteEnumToArray(
+ 1, this->_internal_kind(), target);
+ }
+
+ // .google.protobuf.Field.Cardinality cardinality = 2;
+ if (this->_internal_cardinality() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteEnumToArray(
+ 2, this->_internal_cardinality(), target);
+ }
+
+ // int32 number = 3;
+ if (this->_internal_number() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::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 = ::_pbi::WireFormatLite::WriteInt32ToArray(7, this->_internal_oneof_index(), target);
+ }
+
+ // bool packed = 8;
+ if (this->_internal_packed() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(8, this->_internal_packed(), target);
+ }
+
+ // repeated .google.protobuf.Option options = 9;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_options_size()); i < n; i++) {
+ const auto& repfield = this->_internal_options(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(9, repfield, repfield.GetCachedSize(), 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 = ::_pbi::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;
+
+ uint32_t 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->_impl_.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 +
+ ::_pbi::WireFormatLite::EnumSize(this->_internal_kind());
+ }
+
+ // .google.protobuf.Field.Cardinality cardinality = 2;
+ if (this->_internal_cardinality() != 0) {
+ total_size += 1 +
+ ::_pbi::WireFormatLite::EnumSize(this->_internal_cardinality());
+ }
+
+ // int32 number = 3;
+ if (this->_internal_number() != 0) {
+ total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_number());
+ }
+
+ // int32 oneof_index = 7;
+ if (this->_internal_oneof_index() != 0) {
+ total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_oneof_index());
+ }
+
+ // bool packed = 8;
+ if (this->_internal_packed() != 0) {
+ total_size += 1 + 1;
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Field::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Field::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Field::GetClassData() const { return &_class_data_; }
+
+
+void Field::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Field*>(&to_msg);
+ auto& from = static_cast<const Field&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Field)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.options_.MergeFrom(from._impl_.options_);
+ if (!from._internal_name().empty()) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (!from._internal_type_url().empty()) {
+ _this->_internal_set_type_url(from._internal_type_url());
+ }
+ if (!from._internal_json_name().empty()) {
+ _this->_internal_set_json_name(from._internal_json_name());
+ }
+ if (!from._internal_default_value().empty()) {
+ _this->_internal_set_default_value(from._internal_default_value());
+ }
+ if (from._internal_kind() != 0) {
+ _this->_internal_set_kind(from._internal_kind());
+ }
+ if (from._internal_cardinality() != 0) {
+ _this->_internal_set_cardinality(from._internal_cardinality());
+ }
+ if (from._internal_number() != 0) {
+ _this->_internal_set_number(from._internal_number());
+ }
+ if (from._internal_oneof_index() != 0) {
+ _this->_internal_set_oneof_index(from._internal_oneof_index());
+ }
+ if (from._internal_packed() != 0) {
+ _this->_internal_set_packed(from._internal_packed());
+ }
+ _this->_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_);
+ _impl_.options_.InternalSwap(&other->_impl_.options_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.type_url_, lhs_arena,
+ &other->_impl_.type_url_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.json_name_, lhs_arena,
+ &other->_impl_.json_name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.default_value_, lhs_arena,
+ &other->_impl_.default_value_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(Field, _impl_.packed_)
+ + sizeof(Field::_impl_.packed_)
+ - PROTOBUF_FIELD_OFFSET(Field, _impl_.kind_)>(
+ reinterpret_cast<char*>(&_impl_.kind_),
+ reinterpret_cast<char*>(&other->_impl_.kind_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Field::GetMetadata() const {
+ return ::_pbi::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->_impl_.source_context_;
+}
+void Enum::clear_source_context() {
+ if (GetArenaForAllocation() == nullptr && _impl_.source_context_ != nullptr) {
+ delete _impl_.source_context_;
+ }
+ _impl_.source_context_ = nullptr;
+}
+Enum::Enum(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Enum)
+}
+Enum::Enum(const Enum& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Enum* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.enumvalue_){from._impl_.enumvalue_}
+ , decltype(_impl_.options_){from._impl_.options_}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.source_context_){nullptr}
+ , decltype(_impl_.syntax_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ if (from._internal_has_source_context()) {
+ _this->_impl_.source_context_ = new ::PROTOBUF_NAMESPACE_ID::SourceContext(*from._impl_.source_context_);
+ }
+ _this->_impl_.syntax_ = from._impl_.syntax_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Enum)
+}
+
+inline void Enum::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.enumvalue_){arena}
+ , decltype(_impl_.options_){arena}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.source_context_){nullptr}
+ , decltype(_impl_.syntax_){0}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+Enum::~Enum() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Enum)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Enum::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.enumvalue_.~RepeatedPtrField();
+ _impl_.options_.~RepeatedPtrField();
+ _impl_.name_.Destroy();
+ if (this != internal_default_instance()) delete _impl_.source_context_;
+}
+
+void Enum::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void Enum::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Enum)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.enumvalue_.Clear();
+ _impl_.options_.Clear();
+ _impl_.name_.ClearToEmpty();
+ if (GetArenaForAllocation() == nullptr && _impl_.source_context_ != nullptr) {
+ delete _impl_.source_context_;
+ }
+ _impl_.source_context_ = nullptr;
+ _impl_.syntax_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Enum::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Enum.name"));
+ } 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)) {
+ uint64_t 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)
+ uint32_t 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 i = 0,
+ n = static_cast<unsigned>(this->_internal_enumvalue_size()); i < n; i++) {
+ const auto& repfield = this->_internal_enumvalue(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // repeated .google.protobuf.Option options = 3;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_options_size()); i < n; i++) {
+ const auto& repfield = this->_internal_options(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(3, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ // .google.protobuf.SourceContext source_context = 4;
+ if (this->_internal_has_source_context()) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(4, _Internal::source_context(this),
+ _Internal::source_context(this).GetCachedSize(), target, stream);
+ }
+
+ // .google.protobuf.Syntax syntax = 5;
+ if (this->_internal_syntax() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteEnumToArray(
+ 5, this->_internal_syntax(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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->_impl_.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->_impl_.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(
+ *_impl_.source_context_);
+ }
+
+ // .google.protobuf.Syntax syntax = 5;
+ if (this->_internal_syntax() != 0) {
+ total_size += 1 +
+ ::_pbi::WireFormatLite::EnumSize(this->_internal_syntax());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Enum::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Enum::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Enum::GetClassData() const { return &_class_data_; }
+
+
+void Enum::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Enum*>(&to_msg);
+ auto& from = static_cast<const Enum&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Enum)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.enumvalue_.MergeFrom(from._impl_.enumvalue_);
+ _this->_impl_.options_.MergeFrom(from._impl_.options_);
+ if (!from._internal_name().empty()) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (from._internal_has_source_context()) {
+ _this->_internal_mutable_source_context()->::PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(
+ from._internal_source_context());
+ }
+ if (from._internal_syntax() != 0) {
+ _this->_internal_set_syntax(from._internal_syntax());
+ }
+ _this->_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_);
+ _impl_.enumvalue_.InternalSwap(&other->_impl_.enumvalue_);
+ _impl_.options_.InternalSwap(&other->_impl_.options_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(Enum, _impl_.syntax_)
+ + sizeof(Enum::_impl_.syntax_)
+ - PROTOBUF_FIELD_OFFSET(Enum, _impl_.source_context_)>(
+ reinterpret_cast<char*>(&_impl_.source_context_),
+ reinterpret_cast<char*>(&other->_impl_.source_context_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Enum::GetMetadata() const {
+ return ::_pbi::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) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValue)
+}
+EnumValue::EnumValue(const EnumValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ EnumValue* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.options_){from._impl_.options_}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.number_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ _this->_impl_.number_ = from._impl_.number_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValue)
+}
+
+inline void EnumValue::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.options_){arena}
+ , decltype(_impl_.name_){}
+ , decltype(_impl_.number_){0}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+EnumValue::~EnumValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumValue)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void EnumValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.options_.~RepeatedPtrField();
+ _impl_.name_.Destroy();
+}
+
+void EnumValue::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void EnumValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.options_.Clear();
+ _impl_.name_.ClearToEmpty();
+ _impl_.number_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* EnumValue::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.EnumValue.name"));
+ } else
+ goto handle_unusual;
+ continue;
+ // int32 number = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ _impl_.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)
+ uint32_t 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 = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_number(), target);
+ }
+
+ // repeated .google.protobuf.Option options = 3;
+ for (unsigned i = 0,
+ n = static_cast<unsigned>(this->_internal_options_size()); i < n; i++) {
+ const auto& repfield = this->_internal_options(i);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(3, repfield, repfield.GetCachedSize(), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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->_impl_.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 += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_number());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ EnumValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValue::GetClassData() const { return &_class_data_; }
+
+
+void EnumValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<EnumValue*>(&to_msg);
+ auto& from = static_cast<const EnumValue&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValue)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ _this->_impl_.options_.MergeFrom(from._impl_.options_);
+ if (!from._internal_name().empty()) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (from._internal_number() != 0) {
+ _this->_internal_set_number(from._internal_number());
+ }
+ _this->_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_);
+ _impl_.options_.InternalSwap(&other->_impl_.options_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ swap(_impl_.number_, other->_impl_.number_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata EnumValue::GetMetadata() const {
+ return ::_pbi::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->_impl_.value_;
+}
+void Option::clear_value() {
+ if (GetArenaForAllocation() == nullptr && _impl_.value_ != nullptr) {
+ delete _impl_.value_;
+ }
+ _impl_.value_ = nullptr;
+}
+Option::Option(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Option)
+}
+Option::Option(const Option& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Option* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.name_){}
+ , decltype(_impl_.value_){nullptr}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ _this->_impl_.name_.Set(from._internal_name(),
+ _this->GetArenaForAllocation());
+ }
+ if (from._internal_has_value()) {
+ _this->_impl_.value_ = new ::PROTOBUF_NAMESPACE_ID::Any(*from._impl_.value_);
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Option)
+}
+
+inline void Option::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.name_){}
+ , decltype(_impl_.value_){nullptr}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+ _impl_.name_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.name_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+Option::~Option() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Option)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Option::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.name_.Destroy();
+ if (this != internal_default_instance()) delete _impl_.value_;
+}
+
+void Option::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void Option::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Option)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.name_.ClearToEmpty();
+ if (GetArenaForAllocation() == nullptr && _impl_.value_ != nullptr) {
+ delete _impl_.value_;
+ }
+ _impl_.value_ = nullptr;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Option::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Option.name"));
+ } 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)
+ uint32_t 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, _Internal::value(this),
+ _Internal::value(this).GetCachedSize(), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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(
+ *_impl_.value_);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Option::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Option::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Option::GetClassData() const { return &_class_data_; }
+
+
+void Option::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Option*>(&to_msg);
+ auto& from = static_cast<const Option&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Option)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (!from._internal_name().empty()) {
+ _this->_internal_set_name(from._internal_name());
+ }
+ if (from._internal_has_value()) {
+ _this->_internal_mutable_value()->::PROTOBUF_NAMESPACE_ID::Any::MergeFrom(
+ from._internal_value());
+ }
+ _this->_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(
+ &_impl_.name_, lhs_arena,
+ &other->_impl_.name_, rhs_arena
+ );
+ swap(_impl_.value_, other->_impl_.value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Option::GetMetadata() const {
+ return ::_pbi::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/toolkit/components/protobuf/src/google/protobuf/type.pb.h b/toolkit/components/protobuf/src/google/protobuf/type.pb.h
new file mode 100644
index 0000000000..0f11e6cd1b
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/type.pb.h
@@ -0,0 +1,2571 @@
+// 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 < 3021000
+#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 3021006 < 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_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 uint32_t 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<int32_t>::min(),
+ Field_Kind_Field_Kind_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::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 std::string& Field_Kind_Name(T enum_t_value) {
+ static_assert(::std::is_same<T, Field_Kind>::value ||
+ ::std::is_integral<T>::value,
+ "Incorrect type passed to function Field_Kind_Name.");
+ return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
+ Field_Kind_descriptor(), enum_t_value);
+}
+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<int32_t>::min(),
+ Field_Cardinality_Field_Cardinality_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::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 std::string& Field_Cardinality_Name(T enum_t_value) {
+ static_assert(::std::is_same<T, Field_Cardinality>::value ||
+ ::std::is_integral<T>::value,
+ "Incorrect type passed to function Field_Cardinality_Name.");
+ return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
+ Field_Cardinality_descriptor(), enum_t_value);
+}
+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<int32_t>::min(),
+ Syntax_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::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 std::string& Syntax_Name(T enum_t_value) {
+ static_assert(::std::is_same<T, Syntax>::value ||
+ ::std::is_integral<T>::value,
+ "Incorrect type passed to function Syntax_Name.");
+ return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
+ Syntax_descriptor(), enum_t_value);
+}
+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 PROTOBUF_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) {
+ Type::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& oneofs(int index) const;
+ std::string* mutable_oneofs(int index);
+ void set_oneofs(int index, const std::string& value);
+ void set_oneofs(int index, std::string&& value);
+ void set_oneofs(int index, const char* value);
+ void set_oneofs(int index, const char* value, size_t size);
+ std::string* add_oneofs();
+ void add_oneofs(const std::string& value);
+ void add_oneofs(std::string&& value);
+ void add_oneofs(const char* value);
+ void add_oneofs(const char* value, size_t size);
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& oneofs() const;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_oneofs();
+ private:
+ const std::string& _internal_oneofs(int index) const;
+ std::string* _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 std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Field > fields_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> 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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ Field::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& 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 std::string& 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 std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _internal_mutable_name();
+ public:
+
+ // string type_url = 6;
+ void clear_type_url();
+ const std::string& type_url() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_type_url(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_type_url();
+ PROTOBUF_NODISCARD std::string* release_type_url();
+ void set_allocated_type_url(std::string* type_url);
+ private:
+ const std::string& _internal_type_url() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_type_url(const std::string& value);
+ std::string* _internal_mutable_type_url();
+ public:
+
+ // string json_name = 10;
+ void clear_json_name();
+ const std::string& json_name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_json_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_json_name();
+ PROTOBUF_NODISCARD std::string* release_json_name();
+ void set_allocated_json_name(std::string* json_name);
+ private:
+ const std::string& _internal_json_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_json_name(const std::string& value);
+ std::string* _internal_mutable_json_name();
+ public:
+
+ // string default_value = 11;
+ void clear_default_value();
+ const std::string& default_value() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_default_value(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_default_value();
+ PROTOBUF_NODISCARD std::string* release_default_value();
+ void set_allocated_default_value(std::string* default_value);
+ private:
+ const std::string& _internal_default_value() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_default_value(const std::string& value);
+ std::string* _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();
+ int32_t number() const;
+ void set_number(int32_t value);
+ private:
+ int32_t _internal_number() const;
+ void _internal_set_number(int32_t value);
+ public:
+
+ // int32 oneof_index = 7;
+ void clear_oneof_index();
+ int32_t oneof_index() const;
+ void set_oneof_index(int32_t value);
+ private:
+ int32_t _internal_oneof_index() const;
+ void _internal_set_oneof_index(int32_t 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_;
+ struct Impl_ {
+ ::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_;
+ int32_t number_;
+ int32_t oneof_index_;
+ bool packed_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ Enum::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::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_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ EnumValue::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _internal_mutable_name();
+ public:
+
+ // int32 number = 2;
+ void clear_number();
+ int32_t number() const;
+ void set_number(int32_t value);
+ private:
+ int32_t _internal_number() const;
+ void _internal_set_number(int32_t 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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ int32_t number_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ Option::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& name() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_name(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_name();
+ PROTOBUF_NODISCARD std::string* release_name();
+ void set_allocated_name(std::string* name);
+ private:
+ const std::string& _internal_name() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ ::PROTOBUF_NAMESPACE_ID::Any* value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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() {
+ _impl_.name_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Type.name)
+}
+inline std::string* Type::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Type.name)
+ return _s;
+}
+inline const std::string& Type::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void Type::_internal_set_name(const std::string& value) {
+
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Type::_internal_mutable_name() {
+
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Type::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Type.name)
+ return _impl_.name_.Release();
+}
+inline void Type::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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 _impl_.fields_.size();
+}
+inline int Type::fields_size() const {
+ return _internal_fields_size();
+}
+inline void Type::clear_fields() {
+ _impl_.fields_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Field* Type::mutable_fields(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Type.fields)
+ return _impl_.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 &_impl_.fields_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Field& Type::_internal_fields(int index) const {
+ return _impl_.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 _impl_.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 _impl_.fields_;
+}
+
+// repeated string oneofs = 3;
+inline int Type::_internal_oneofs_size() const {
+ return _impl_.oneofs_.size();
+}
+inline int Type::oneofs_size() const {
+ return _internal_oneofs_size();
+}
+inline void Type::clear_oneofs() {
+ _impl_.oneofs_.Clear();
+}
+inline std::string* Type::add_oneofs() {
+ std::string* _s = _internal_add_oneofs();
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.Type.oneofs)
+ return _s;
+}
+inline const std::string& Type::_internal_oneofs(int index) const {
+ return _impl_.oneofs_.Get(index);
+}
+inline const std::string& Type::oneofs(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Type.oneofs)
+ return _internal_oneofs(index);
+}
+inline std::string* Type::mutable_oneofs(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Type.oneofs)
+ return _impl_.oneofs_.Mutable(index);
+}
+inline void Type::set_oneofs(int index, const std::string& value) {
+ _impl_.oneofs_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs)
+}
+inline void Type::set_oneofs(int index, std::string&& value) {
+ _impl_.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);
+ _impl_.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) {
+ _impl_.oneofs_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.Type.oneofs)
+}
+inline std::string* Type::_internal_add_oneofs() {
+ return _impl_.oneofs_.Add();
+}
+inline void Type::add_oneofs(const std::string& value) {
+ _impl_.oneofs_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs)
+}
+inline void Type::add_oneofs(std::string&& value) {
+ _impl_.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);
+ _impl_.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) {
+ _impl_.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<std::string>&
+Type::oneofs() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Type.oneofs)
+ return _impl_.oneofs_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
+Type::mutable_oneofs() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.oneofs)
+ return &_impl_.oneofs_;
+}
+
+// repeated .google.protobuf.Option options = 4;
+inline int Type::_internal_options_size() const {
+ return _impl_.options_.size();
+}
+inline int Type::options_size() const {
+ return _internal_options_size();
+}
+inline void Type::clear_options() {
+ _impl_.options_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Type::mutable_options(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Type.options)
+ return _impl_.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 &_impl_.options_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Type::_internal_options(int index) const {
+ return _impl_.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 _impl_.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 _impl_.options_;
+}
+
+// .google.protobuf.SourceContext source_context = 5;
+inline bool Type::_internal_has_source_context() const {
+ return this != internal_default_instance() && _impl_.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 = _impl_.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*>(_impl_.source_context_);
+ }
+ _impl_.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 = _impl_.source_context_;
+ _impl_.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 = _impl_.source_context_;
+ _impl_.source_context_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Type::_internal_mutable_source_context() {
+
+ if (_impl_.source_context_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(GetArenaForAllocation());
+ _impl_.source_context_ = p;
+ }
+ return _impl_.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*>(_impl_.source_context_);
+ }
+ if (source_context) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(
+ 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 {
+
+ }
+ _impl_.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() {
+ _impl_.syntax_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Syntax Type::_internal_syntax() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(_impl_.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) {
+
+ _impl_.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() {
+ _impl_.kind_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Field_Kind Field::_internal_kind() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::Field_Kind >(_impl_.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) {
+
+ _impl_.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() {
+ _impl_.cardinality_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Field_Cardinality Field::_internal_cardinality() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::Field_Cardinality >(_impl_.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) {
+
+ _impl_.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() {
+ _impl_.number_ = 0;
+}
+inline int32_t Field::_internal_number() const {
+ return _impl_.number_;
+}
+inline int32_t Field::number() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Field.number)
+ return _internal_number();
+}
+inline void Field::_internal_set_number(int32_t value) {
+
+ _impl_.number_ = value;
+}
+inline void Field::set_number(int32_t value) {
+ _internal_set_number(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.number)
+}
+
+// string name = 4;
+inline void Field::clear_name() {
+ _impl_.name_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.name)
+}
+inline std::string* Field::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Field.name)
+ return _s;
+}
+inline const std::string& Field::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void Field::_internal_set_name(const std::string& value) {
+
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Field::_internal_mutable_name() {
+
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Field::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.name)
+ return _impl_.name_.Release();
+}
+inline void Field::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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() {
+ _impl_.type_url_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.type_url_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url)
+}
+inline std::string* Field::mutable_type_url() {
+ std::string* _s = _internal_mutable_type_url();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Field.type_url)
+ return _s;
+}
+inline const std::string& Field::_internal_type_url() const {
+ return _impl_.type_url_.Get();
+}
+inline void Field::_internal_set_type_url(const std::string& value) {
+
+ _impl_.type_url_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Field::_internal_mutable_type_url() {
+
+ return _impl_.type_url_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Field::release_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.type_url)
+ return _impl_.type_url_.Release();
+}
+inline void Field::set_allocated_type_url(std::string* type_url) {
+ if (type_url != nullptr) {
+
+ } else {
+
+ }
+ _impl_.type_url_.SetAllocated(type_url, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.type_url_.IsDefault()) {
+ _impl_.type_url_.Set("", 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() {
+ _impl_.oneof_index_ = 0;
+}
+inline int32_t Field::_internal_oneof_index() const {
+ return _impl_.oneof_index_;
+}
+inline int32_t 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(int32_t value) {
+
+ _impl_.oneof_index_ = value;
+}
+inline void Field::set_oneof_index(int32_t value) {
+ _internal_set_oneof_index(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.oneof_index)
+}
+
+// bool packed = 8;
+inline void Field::clear_packed() {
+ _impl_.packed_ = false;
+}
+inline bool Field::_internal_packed() const {
+ return _impl_.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) {
+
+ _impl_.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 _impl_.options_.size();
+}
+inline int Field::options_size() const {
+ return _internal_options_size();
+}
+inline void Field::clear_options() {
+ _impl_.options_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Field::mutable_options(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Field.options)
+ return _impl_.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 &_impl_.options_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Field::_internal_options(int index) const {
+ return _impl_.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 _impl_.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 _impl_.options_;
+}
+
+// string json_name = 10;
+inline void Field::clear_json_name() {
+ _impl_.json_name_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.json_name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name)
+}
+inline std::string* Field::mutable_json_name() {
+ std::string* _s = _internal_mutable_json_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Field.json_name)
+ return _s;
+}
+inline const std::string& Field::_internal_json_name() const {
+ return _impl_.json_name_.Get();
+}
+inline void Field::_internal_set_json_name(const std::string& value) {
+
+ _impl_.json_name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Field::_internal_mutable_json_name() {
+
+ return _impl_.json_name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Field::release_json_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.json_name)
+ return _impl_.json_name_.Release();
+}
+inline void Field::set_allocated_json_name(std::string* json_name) {
+ if (json_name != nullptr) {
+
+ } else {
+
+ }
+ _impl_.json_name_.SetAllocated(json_name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.json_name_.IsDefault()) {
+ _impl_.json_name_.Set("", 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() {
+ _impl_.default_value_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.default_value_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value)
+}
+inline std::string* Field::mutable_default_value() {
+ std::string* _s = _internal_mutable_default_value();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Field.default_value)
+ return _s;
+}
+inline const std::string& Field::_internal_default_value() const {
+ return _impl_.default_value_.Get();
+}
+inline void Field::_internal_set_default_value(const std::string& value) {
+
+ _impl_.default_value_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Field::_internal_mutable_default_value() {
+
+ return _impl_.default_value_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Field::release_default_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.default_value)
+ return _impl_.default_value_.Release();
+}
+inline void Field::set_allocated_default_value(std::string* default_value) {
+ if (default_value != nullptr) {
+
+ } else {
+
+ }
+ _impl_.default_value_.SetAllocated(default_value, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.default_value_.IsDefault()) {
+ _impl_.default_value_.Set("", 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() {
+ _impl_.name_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Enum.name)
+}
+inline std::string* Enum::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.name)
+ return _s;
+}
+inline const std::string& Enum::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void Enum::_internal_set_name(const std::string& value) {
+
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Enum::_internal_mutable_name() {
+
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Enum::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Enum.name)
+ return _impl_.name_.Release();
+}
+inline void Enum::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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 _impl_.enumvalue_.size();
+}
+inline int Enum::enumvalue_size() const {
+ return _internal_enumvalue_size();
+}
+inline void Enum::clear_enumvalue() {
+ _impl_.enumvalue_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValue* Enum::mutable_enumvalue(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.enumvalue)
+ return _impl_.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 &_impl_.enumvalue_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumValue& Enum::_internal_enumvalue(int index) const {
+ return _impl_.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 _impl_.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 _impl_.enumvalue_;
+}
+
+// repeated .google.protobuf.Option options = 3;
+inline int Enum::_internal_options_size() const {
+ return _impl_.options_.size();
+}
+inline int Enum::options_size() const {
+ return _internal_options_size();
+}
+inline void Enum::clear_options() {
+ _impl_.options_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Enum::mutable_options(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.options)
+ return _impl_.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 &_impl_.options_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Enum::_internal_options(int index) const {
+ return _impl_.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 _impl_.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 _impl_.options_;
+}
+
+// .google.protobuf.SourceContext source_context = 4;
+inline bool Enum::_internal_has_source_context() const {
+ return this != internal_default_instance() && _impl_.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 = _impl_.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*>(_impl_.source_context_);
+ }
+ _impl_.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 = _impl_.source_context_;
+ _impl_.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 = _impl_.source_context_;
+ _impl_.source_context_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Enum::_internal_mutable_source_context() {
+
+ if (_impl_.source_context_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(GetArenaForAllocation());
+ _impl_.source_context_ = p;
+ }
+ return _impl_.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*>(_impl_.source_context_);
+ }
+ if (source_context) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(
+ 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 {
+
+ }
+ _impl_.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() {
+ _impl_.syntax_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Syntax Enum::_internal_syntax() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(_impl_.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) {
+
+ _impl_.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() {
+ _impl_.name_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name)
+}
+inline std::string* EnumValue::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.name)
+ return _s;
+}
+inline const std::string& EnumValue::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void EnumValue::_internal_set_name(const std::string& value) {
+
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* EnumValue::_internal_mutable_name() {
+
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* EnumValue::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumValue.name)
+ return _impl_.name_.Release();
+}
+inline void EnumValue::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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() {
+ _impl_.number_ = 0;
+}
+inline int32_t EnumValue::_internal_number() const {
+ return _impl_.number_;
+}
+inline int32_t EnumValue::number() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.number)
+ return _internal_number();
+}
+inline void EnumValue::_internal_set_number(int32_t value) {
+
+ _impl_.number_ = value;
+}
+inline void EnumValue::set_number(int32_t 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 _impl_.options_.size();
+}
+inline int EnumValue::options_size() const {
+ return _internal_options_size();
+}
+inline void EnumValue::clear_options() {
+ _impl_.options_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* EnumValue::mutable_options(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.options)
+ return _impl_.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 &_impl_.options_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& EnumValue::_internal_options(int index) const {
+ return _impl_.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 _impl_.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 _impl_.options_;
+}
+
+// -------------------------------------------------------------------
+
+// Option
+
+// string name = 1;
+inline void Option::clear_name() {
+ _impl_.name_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Option.name)
+}
+inline std::string* Option::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Option.name)
+ return _s;
+}
+inline const std::string& Option::_internal_name() const {
+ return _impl_.name_.Get();
+}
+inline void Option::_internal_set_name(const std::string& value) {
+
+ _impl_.name_.Set(value, GetArenaForAllocation());
+}
+inline std::string* Option::_internal_mutable_name() {
+
+ return _impl_.name_.Mutable(GetArenaForAllocation());
+}
+inline std::string* Option::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Option.name)
+ return _impl_.name_.Release();
+}
+inline void Option::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ _impl_.name_.SetAllocated(name, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.name_.IsDefault()) {
+ _impl_.name_.Set("", 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() && _impl_.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 = _impl_.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*>(_impl_.value_);
+ }
+ _impl_.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 = _impl_.value_;
+ _impl_.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 = _impl_.value_;
+ _impl_.value_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Any* Option::_internal_mutable_value() {
+
+ if (_impl_.value_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Any>(GetArenaForAllocation());
+ _impl_.value_ = p;
+ }
+ return _impl_.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*>(_impl_.value_);
+ }
+ if (value) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(
+ reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(value));
+ if (message_arena != submessage_arena) {
+ value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, value, submessage_arena);
+ }
+
+ } else {
+
+ }
+ _impl_.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/toolkit/components/protobuf/src/google/protobuf/type.proto b/toolkit/components/protobuf/src/google/protobuf/type.proto
new file mode 100644
index 0000000000..d3f6a68b83
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/unknown_field_set.cc b/toolkit/components/protobuf/src/google/protobuf/unknown_field_set.cc
new file mode 100644
index 0000000000..74c358e9a2
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/unknown_field_set.cc
@@ -0,0 +1,350 @@
+// 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/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/extension_set.h>
+#include <google/protobuf/generated_message_tctable_decl.h>
+#include <google/protobuf/generated_message_tctable_impl.h>
+#include <google/protobuf/parse_context.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/stubs/stl_util.h>
+
+// Must be included last.
+#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(UnknownField) * fields_.capacity();
+
+ 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, uint64_t value) {
+ UnknownField field;
+ field.number_ = number;
+ field.SetType(UnknownField::TYPE_VARINT);
+ field.data_.varint_ = value;
+ fields_.push_back(field);
+}
+
+void UnknownFieldSet::AddFixed32(int number, uint32_t value) {
+ UnknownField field;
+ field.number_ = number;
+ field.SetType(UnknownField::TYPE_FIXED32);
+ field.data_.fixed32_ = value;
+ fields_.push_back(field);
+}
+
+void UnknownFieldSet::AddFixed64(int number, uint64_t value) {
+ UnknownField field;
+ field.number_ = number;
+ field.SetType(UnknownField::TYPE_FIXED64);
+ field.data_.fixed64_ = value;
+ fields_.push_back(field);
+}
+
+std::string* UnknownFieldSet::AddLengthDelimited(int number) {
+ UnknownField field;
+ field.number_ = number;
+ field.SetType(UnknownField::TYPE_LENGTH_DELIMITED);
+ field.data_.length_delimited_.string_value = new std::string;
+ 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);
+}
+
+bool UnknownFieldSet::SerializeToString(std::string* output) const {
+ const size_t size =
+ google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(*this);
+ STLStringResizeUninitializedAmortized(output, size);
+ google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ *this, reinterpret_cast<uint8_t*>(const_cast<char*>(output->data())));
+ return true;
+}
+
+bool UnknownFieldSet::SerializeToCodedStream(
+ io::CodedOutputStream* output) const {
+ google::protobuf::internal::WireFormat::SerializeUnknownFields(*this, output);
+ return !output->HadError();
+}
+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 std::string(*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 std::string& 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(uint32_t num, uint64_t value) {
+ unknown_->AddVarint(num, value);
+ }
+ void AddFixed64(uint32_t num, uint64_t value) {
+ unknown_->AddFixed64(num, value);
+ }
+ const char* ParseLengthDelimited(uint32_t num, const char* ptr,
+ ParseContext* ctx) {
+ std::string* s = unknown_->AddLengthDelimited(num);
+ int size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ return ctx->ReadString(ptr, size, s);
+ }
+ const char* ParseGroup(uint32_t num, const char* ptr, ParseContext* ctx) {
+ UnknownFieldParserHelper child(unknown_->AddGroup(num));
+ return ctx->ParseGroup(&child, ptr, num * 8 + 3);
+ }
+ void AddFixed32(uint32_t num, uint32_t 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(uint64_t 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/toolkit/components/protobuf/src/google/protobuf/unknown_field_set.h b/toolkit/components/protobuf/src/google/protobuf/unknown_field_set.h
new file mode 100644
index 0000000000..9aa2cbbe47
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/unknown_field_set.h
@@ -0,0 +1,407 @@
+// 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/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/port.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/parse_context.h>
+
+// Must be included last.
+#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, uint64_t value);
+ void AddFixed32(int number, uint32_t value);
+ void AddFixed64(int number, uint64_t value);
+ void AddLengthDelimited(int number, const std::string& value);
+ std::string* 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 std::string& 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);
+
+ // Serialization.
+ bool SerializeToString(std::string* output) const;
+ bool SerializeToCodedStream(io::CodedOutputStream* output) const;
+ 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(uint32_t num, uint64_t val, UnknownFieldSet* unknown) {
+ unknown->AddVarint(num, val);
+}
+inline void WriteLengthDelimited(uint32_t 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(uint64_t 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 uint64_t varint() const;
+ inline uint32_t fixed32() const;
+ inline uint64_t fixed64() const;
+ inline const std::string& length_delimited() const;
+ inline const UnknownFieldSet& group() const;
+
+ inline void set_varint(uint64_t value);
+ inline void set_fixed32(uint32_t value);
+ inline void set_fixed64(uint64_t value);
+ inline void set_length_delimited(const std::string& value);
+ inline std::string* mutable_length_delimited();
+ inline UnknownFieldSet* mutable_group();
+
+ 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 {
+ std::string* string_value;
+ };
+
+ uint32_t number_;
+ uint32_t type_;
+ union {
+ uint64_t varint_;
+ uint32_t fixed32_;
+ uint64_t 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 std::string& 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 uint64_t UnknownField::varint() const {
+ assert(type() == TYPE_VARINT);
+ return data_.varint_;
+}
+inline uint32_t UnknownField::fixed32() const {
+ assert(type() == TYPE_FIXED32);
+ return data_.fixed32_;
+}
+inline uint64_t UnknownField::fixed64() const {
+ assert(type() == TYPE_FIXED64);
+ return data_.fixed64_;
+}
+inline const std::string& 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(uint64_t value) {
+ assert(type() == TYPE_VARINT);
+ data_.varint_ = value;
+}
+inline void UnknownField::set_fixed32(uint32_t value) {
+ assert(type() == TYPE_FIXED32);
+ data_.fixed32_ = value;
+}
+inline void UnknownField::set_fixed64(uint64_t value) {
+ assert(type() == TYPE_FIXED64);
+ data_.fixed64_ = value;
+}
+inline void UnknownField::set_length_delimited(const std::string& value) {
+ assert(type() == TYPE_LENGTH_DELIMITED);
+ data_.length_delimited_.string_value->assign(value);
+}
+inline std::string* 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/toolkit/components/protobuf/src/google/protobuf/util/delimited_message_util.cc b/toolkit/components/protobuf/src/google/protobuf/util/delimited_message_util.cc
new file mode 100644
index 0000000000..fdc633f49a
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/delimited_message_util.cc
@@ -0,0 +1,128 @@
+// 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 != nullptr) *clean_eof = false;
+ int start = input->CurrentPosition();
+
+ // Read the size.
+ uint32_t size;
+ if (!input->ReadVarint32(&size)) {
+ if (clean_eof != nullptr) *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(static_cast<int>(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(static_cast<uint32_t>(size));
+
+ // Write the content.
+ uint8_t* buffer =
+ output->GetDirectBufferForNBytesAndAdvance(static_cast<int>(size));
+ if (buffer != nullptr) {
+ // 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/toolkit/components/protobuf/src/google/protobuf/util/delimited_message_util.h b/toolkit/components/protobuf/src/google/protobuf/util/delimited_message_util.h
new file mode 100644
index 0000000000..78625cf2f1
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/delimited_message_util.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.
+
+// 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>
+
+// Must be included last.
+#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/toolkit/components/protobuf/src/google/protobuf/util/field_comparator.cc b/toolkit/components/protobuf/src/google/protobuf/util/field_comparator.cc
new file mode 100644
index 0000000000..5d8e865ad8
--- /dev/null
+++ b/toolkit/components/protobuf/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.
+ std::string scratch1;
+ std::string 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.
+ std::string scratch1;
+ std::string 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/toolkit/components/protobuf/src/google/protobuf/util/field_comparator.h b/toolkit/components/protobuf/src/google/protobuf/util/field_comparator.h
new file mode 100644
index 0000000000..5706da357a
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/field_comparator.h
@@ -0,0 +1,288 @@
+// 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>
+
+// Must be included last.
+#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 */, int32_t value_1,
+ int32_t value_2) {
+ return value_1 == value_2;
+ }
+
+ bool CompareInt64(const FieldDescriptor& /* unused */, int64_t value_1,
+ int64_t value_2) {
+ return value_1 == value_2;
+ }
+
+ bool CompareString(const FieldDescriptor& /* unused */,
+ const std::string& value_1, const std::string& value_2) {
+ return value_1 == value_2;
+ }
+
+ bool CompareUInt32(const FieldDescriptor& /* unused */, uint32_t value_1,
+ uint32_t value_2) {
+ return value_1 == value_2;
+ }
+
+ bool CompareUInt64(const FieldDescriptor& /* unused */, uint64_t value_1,
+ uint64_t 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/toolkit/components/protobuf/src/google/protobuf/util/field_mask_util.cc b/toolkit/components/protobuf/src/google/protobuf/util/field_mask_util.cc
new file mode 100644
index 0000000000..700e59004a
--- /dev/null
+++ b/toolkit/components/protobuf/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/stubs/strutil.h>
+#include <google/protobuf/message.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;
+
+std::string FieldMaskUtil::ToString(const FieldMask& mask) {
+ return Join(mask.paths(), ",");
+}
+
+void FieldMaskUtil::FromString(StringPiece str, FieldMask* out) {
+ out->Clear();
+ std::vector<std::string> paths = Split(str, ",");
+ for (const std::string& path : paths) {
+ if (path.empty()) continue;
+ out->add_paths(path);
+ }
+}
+
+bool FieldMaskUtil::SnakeCaseToCamelCase(StringPiece input,
+ std::string* 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,
+ std::string* 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, std::string* out) {
+ out->clear();
+ for (int i = 0; i < mask.paths_size(); ++i) {
+ const std::string& path = mask.paths(i);
+ std::string 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<std::string> paths = Split(str, ",");
+ for (const std::string& path : paths) {
+ if (path.empty()) continue;
+ std::string 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<std::string> parts = Split(path, ".");
+ for (const std::string& 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 std::string& 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 std::string& 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 std::string& 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<std::string, Node*>::iterator it = children.begin();
+ it != children.end(); ++it) {
+ delete it->second;
+ }
+ children.clear();
+ }
+
+ std::map<std::string, 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 std::string& prefix, const Node* node,
+ FieldMask* out);
+
+ // Merge all leaf nodes of a sub-tree to another tree.
+ void MergeLeafNodesToTree(const std::string& 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 std::string& 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<std::string, Node*>::const_iterator it = node->children.begin();
+ it != node->children.end(); ++it) {
+ std::string current_path =
+ prefix.empty() ? it->first : prefix + "." + it->first;
+ MergeToFieldMask(current_path, it->second, out);
+ }
+}
+
+void FieldMaskTree::AddPath(const std::string& path) {
+ std::vector<std::string> parts = Split(path, ".");
+ if (parts.empty()) {
+ return;
+ }
+ bool new_branch = false;
+ Node* node = &root_;
+ for (const std::string& 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 == nullptr) {
+ new_branch = true;
+ child = new Node();
+ }
+ node = child;
+ }
+ if (!node->children.empty()) {
+ node->ClearChildren();
+ }
+}
+
+void FieldMaskTree::RemovePath(const std::string& 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<std::string> 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 std::string& path, FieldMaskTree* out) {
+ std::vector<std::string> parts = Split(path, ".");
+ if (parts.empty()) {
+ return;
+ }
+ const Node* node = &root_;
+ for (const std::string& node_name : parts) {
+ if (node->children.empty()) {
+ if (node != &root_) {
+ out->AddPath(path);
+ }
+ return;
+ }
+ const Node* result = FindPtrOrNull(node->children, node_name);
+ if (result == nullptr) {
+ // 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 std::string& prefix,
+ const Node* node, FieldMaskTree* out) {
+ if (node->children.empty()) {
+ out->AddPath(prefix);
+ }
+ for (std::map<std::string, Node*>::const_iterator it = node->children.begin();
+ it != node->children.end(); ++it) {
+ std::string 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<std::string, Node*>::const_iterator it = node->children.begin();
+ it != node->children.end(); ++it) {
+ const std::string& field_name = it->first;
+ const Node* child = it->second;
+ const FieldDescriptor* field = descriptor->FindFieldByName(field_name);
+ if (field == nullptr) {
+ 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 int32_t field_count = descriptor->field_count();
+ for (int index = 0; index < field_count; ++index) {
+ const FieldDescriptor* field = descriptor->field(index);
+ if (field->is_required()) {
+ const std::string& 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<std::string, 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 int32_t field_count = descriptor->field_count();
+ bool modified = false;
+ for (int index = 0; index < field_count; ++index) {
+ const FieldDescriptor* field = descriptor->field(index);
+ std::map<std::string, 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 std::string& 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/toolkit/components/protobuf/src/google/protobuf/util/field_mask_util.h b/toolkit/components/protobuf/src/google/protobuf/util/field_mask_util.h
new file mode 100644
index 0000000000..d51a332c8b
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/field_mask_util.h
@@ -0,0 +1,263 @@
+// 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/stubs/strutil.h>
+#include <google/protobuf/descriptor.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 std::string 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<int64_t>& 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, std::string* 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(std::string(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,
+ std::string* 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,
+ std::string* 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/toolkit/components/protobuf/src/google/protobuf/util/internal/constants.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/constants.h
new file mode 100644
index 0000000000..8bded86998
--- /dev/null
+++ b/toolkit/components/protobuf/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_INTERNAL_CONSTANTS_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_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 int64_t kTimestampMinSeconds = -62135596800LL;
+
+// Maximum seconds allowed in a google.protobuf.Timestamp value.
+const int64_t kTimestampMaxSeconds = 253402300799LL;
+
+// Minimum seconds allowed in a google.protobuf.Duration value.
+const int64_t kDurationMinSeconds = -315576000000LL;
+
+// Maximum seconds allowed in a google.protobuf.Duration value.
+const int64_t kDurationMaxSeconds = 315576000000LL;
+
+// Nano seconds in a second.
+const int32_t 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_INTERNAL_CONSTANTS_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/datapiece.cc b/toolkit/components/protobuf/src/google/protobuf/util/internal/datapiece.cc
new file mode 100644
index 0000000000..3e7aa84da7
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/datapiece.cc
@@ -0,0 +1,441 @@
+// 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/stubs/status.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/util/internal/utility.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()) {
+ // Some doubles are larger than the largest float, but after
+ // rounding they will be equal to the largest float.
+ // We can't just attempt the conversion because that has UB if
+ // the value really is out-of-range.
+ // Here we take advantage that 1/2-ing a large floating point
+ // will not lose precision.
+ double half_before = before * 0.5;
+ if (half_before < std::numeric_limits<float>::max() &&
+ half_before > -std::numeric_limits<float>::max()) {
+ const float half_fmax = std::numeric_limits<float>::max() * 0.5f;
+ // If after being cut in half, the value is less than the largest float,
+ // then it's safe to convert it to float. Importantly, this conversion
+ // rounds in the same way that the original does.
+ float half_after = static_cast<float>(half_before);
+ if (half_after <= half_fmax && half_after >= -half_fmax) {
+ return half_after + half_after;
+ }
+ }
+ // Double value outside of the range of float.
+ return util::InvalidArgumentError(DoubleAsString(before));
+ } else {
+ return static_cast<float>(before);
+ }
+}
+
+} // namespace
+
+util::StatusOr<int32_t> DataPiece::ToInt32() const {
+ if (type_ == TYPE_STRING)
+ return StringToNumber<int32_t>(safe_strto32);
+
+ if (type_ == TYPE_DOUBLE)
+ return FloatingPointToIntConvertAndCheck<int32_t, double>(double_);
+
+ if (type_ == TYPE_FLOAT)
+ return FloatingPointToIntConvertAndCheck<int32_t, float>(float_);
+
+ return GenericConvert<int32_t>();
+}
+
+util::StatusOr<uint32_t> DataPiece::ToUint32() const {
+ if (type_ == TYPE_STRING)
+ return StringToNumber<uint32_t>(safe_strtou32);
+
+ if (type_ == TYPE_DOUBLE)
+ return FloatingPointToIntConvertAndCheck<uint32_t, double>(double_);
+
+ if (type_ == TYPE_FLOAT)
+ return FloatingPointToIntConvertAndCheck<uint32_t, float>(float_);
+
+ return GenericConvert<uint32_t>();
+}
+
+util::StatusOr<int64_t> DataPiece::ToInt64() const {
+ if (type_ == TYPE_STRING)
+ return StringToNumber<int64_t>(safe_strto64);
+
+ if (type_ == TYPE_DOUBLE)
+ return FloatingPointToIntConvertAndCheck<int64_t, double>(double_);
+
+ if (type_ == TYPE_FLOAT)
+ return FloatingPointToIntConvertAndCheck<int64_t, float>(float_);
+
+ return GenericConvert<int64_t>();
+}
+
+util::StatusOr<uint64_t> DataPiece::ToUint64() const {
+ if (type_ == TYPE_STRING)
+ return StringToNumber<uint64_t>(safe_strtou64);
+
+ if (type_ == TYPE_DOUBLE)
+ return FloatingPointToIntConvertAndCheck<uint64_t, double>(double_);
+
+ if (type_ == TYPE_FLOAT)
+ return FloatingPointToIntConvertAndCheck<uint64_t, float>(float_);
+
+ return GenericConvert<uint64_t>();
+}
+
+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<std::string> DataPiece::ToString() const {
+ switch (type_) {
+ case TYPE_STRING:
+ return std::string(str_);
+ case TYPE_BYTES: {
+ std::string base64;
+ Base64Escape(str_, &base64);
+ return base64;
+ }
+ default:
+ return util::InvalidArgumentError(
+ ValueAsStringOrDefault("Cannot convert to string."));
+ }
+}
+
+std::string 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: {
+ std::string base64;
+ WebSafeBase64Escape(str_, &base64);
+ return StrCat("\"", base64, "\"");
+ }
+ case TYPE_NULL:
+ return "null";
+ default:
+ return std::string(default_string);
+ }
+}
+
+util::StatusOr<std::string> DataPiece::ToBytes() const {
+ if (type_ == TYPE_BYTES) return str_.ToString();
+ if (type_ == TYPE_STRING) {
+ std::string 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.
+ std::string enum_name = std::string(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<int32_t> 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 (std::string::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, int32_t>(i32_);
+ case TYPE_INT64:
+ return NumberConvertAndCheck<To, int64_t>(i64_);
+ case TYPE_UINT32:
+ return NumberConvertAndCheck<To, uint32_t>(u32_);
+ case TYPE_UINT64:
+ return NumberConvertAndCheck<To, uint64_t>(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("\"", std::string(str_), "\""));
+}
+
+bool DataPiece::DecodeBase64(StringPiece src, std::string* 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.
+ std::string 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_) {
+ std::string 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/toolkit/components/protobuf/src/google/protobuf/util/internal/datapiece.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/datapiece.h
new file mode 100644
index 0000000000..6d08349acd
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/datapiece.h
@@ -0,0 +1,219 @@
+// 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_DATAPIECE_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_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>
+
+// Must be included last.
+#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 int32_t value)
+ : type_(TYPE_INT32), i32_(value), use_strict_base64_decoding_(false) {}
+ explicit DataPiece(const int64_t value)
+ : type_(TYPE_INT64), i64_(value), use_strict_base64_decoding_(false) {}
+ explicit DataPiece(const uint32_t value)
+ : type_(TYPE_UINT32), u32_(value), use_strict_base64_decoding_(false) {}
+ explicit DataPiece(const uint64_t 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<int32_t> ToInt32() const;
+
+ // Parses, casts or converts the value stored in the DataPiece into a uint32.
+ util::StatusOr<uint32_t> ToUint32() const;
+
+ // Parses, casts or converts the value stored in the DataPiece into an int64.
+ util::StatusOr<int64_t> ToInt64() const;
+
+ // Parses, casts or converts the value stored in the DataPiece into a uint64.
+ util::StatusOr<uint64_t> 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<std::string> ToString() const;
+
+ // Tries to convert the value contained in this datapiece to string. If the
+ // conversion fails, it returns the default_string.
+ std::string ValueAsStringOrDefault(StringPiece default_string) const;
+
+ util::StatusOr<std::string> ToBytes() const;
+
+ private:
+ friend class ProtoWriter;
+
+ // Disallow implicit constructor.
+ DataPiece();
+
+ // Helper to create NULL or ENUM types.
+ DataPiece(Type type, int32_t 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, std::string* 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 {
+ int32_t i32_;
+ int64_t i64_;
+ uint32_t u32_;
+ uint64_t 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_INTERNAL_DATAPIECE_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/default_value_objectwriter.cc b/toolkit/components/protobuf/src/google/protobuf/util/internal/default_value_objectwriter.cc
new file mode 100644
index 0000000000..7f61cdafa7
--- /dev/null
+++ b/toolkit/components/protobuf/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, int32_t value) {
+ if (current_ == nullptr) {
+ ow_->RenderInt32(name, value);
+ } else {
+ RenderDataPiece(name, DataPiece(value));
+ }
+ return this;
+}
+
+DefaultValueObjectWriter* DefaultValueObjectWriter::RenderUint32(
+ StringPiece name, uint32_t value) {
+ if (current_ == nullptr) {
+ ow_->RenderUint32(name, value);
+ } else {
+ RenderDataPiece(name, DataPiece(value));
+ }
+ return this;
+}
+
+DefaultValueObjectWriter* DefaultValueObjectWriter::RenderInt64(
+ StringPiece name, int64_t value) {
+ if (current_ == nullptr) {
+ ow_->RenderInt64(name, value);
+ } else {
+ RenderDataPiece(name, DataPiece(value));
+ }
+ return this;
+}
+
+DefaultValueObjectWriter* DefaultValueObjectWriter::RenderUint64(
+ StringPiece name, uint64_t 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 std::string(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 std::string(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 std::string& name, const google::protobuf::Type* type, NodeKind kind,
+ const DataPiece& data, bool is_placeholder,
+ const std::vector<std::string>& 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 std::string& name, const google::protobuf::Type* type, NodeKind kind,
+ const DataPiece& data, bool is_placeholder,
+ const std::vector<std::string>& 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<std::string, 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<std::string> 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<std::string, 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 std::string& 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<int64_t>(
+ field.default_value(), &DataPiece::ToInt64, static_cast<int64_t>(0)));
+ }
+ case google::protobuf::Field::TYPE_UINT64:
+ case google::protobuf::Field::TYPE_FIXED64: {
+ return DataPiece(ConvertTo<uint64_t>(field.default_value(),
+ &DataPiece::ToUint64,
+ static_cast<uint64_t>(0)));
+ }
+ case google::protobuf::Field::TYPE_INT32:
+ case google::protobuf::Field::TYPE_SINT32:
+ case google::protobuf::Field::TYPE_SFIXED32: {
+ return DataPiece(ConvertTo<int32_t>(
+ field.default_value(), &DataPiece::ToInt32, static_cast<int32_t>(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<uint32_t>(field.default_value(),
+ &DataPiece::ToUint32,
+ static_cast<uint32_t>(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<std::string> path;
+ root_.reset(CreateNewNode(std::string(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(std::string(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<std::string> path;
+ root_.reset(CreateNewNode(std::string(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(
+ std::string(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<std::string> data_string = data.ToString();
+ if (data_string.ok()) {
+ const std::string& 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(std::string(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/toolkit/components/protobuf/src/google/protobuf/util/internal/default_value_objectwriter.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/default_value_objectwriter.h
new file mode 100644
index 0000000000..a9e1673fa1
--- /dev/null
+++ b/toolkit/components/protobuf/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_INTERNAL_DEFAULT_VALUE_OBJECTWRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_DEFAULT_VALUE_OBJECTWRITER_H__
+
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <stack>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/util/internal/datapiece.h>
+#include <google/protobuf/util/internal/object_writer.h>
+#include <google/protobuf/util/internal/type_info.h>
+#include <google/protobuf/util/internal/utility.h>
+#include <google/protobuf/util/type_resolver.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<std::string>& /*path of the field*/,
+ const google::protobuf::Field* /*field*/)>
+ FieldScrubCallBack;
+
+ DefaultValueObjectWriter(TypeResolver* type_resolver,
+ const google::protobuf::Type& type,
+ ObjectWriter* ow);
+
+ ~DefaultValueObjectWriter() override;
+
+ // 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,
+ int32_t value) override;
+
+ DefaultValueObjectWriter* RenderUint32(StringPiece name,
+ uint32_t value) override;
+
+ DefaultValueObjectWriter* RenderInt64(StringPiece name,
+ int64_t value) override;
+
+ DefaultValueObjectWriter* RenderUint64(StringPiece name,
+ uint64_t 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 std::string& name, const google::protobuf::Type* type,
+ NodeKind kind, const DataPiece& data, bool is_placeholder,
+ const std::vector<std::string>& 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 std::string& name() const { return name_; }
+
+ const std::vector<std::string>& 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.
+ std::string 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<std::string> 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 std::string& name,
+ const google::protobuf::Type* type, NodeKind kind,
+ const DataPiece& data, bool is_placeholder,
+ const std::vector<std::string>& 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<std::string>> 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_INTERNAL_DEFAULT_VALUE_OBJECTWRITER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/error_listener.cc b/toolkit/components/protobuf/src/google/protobuf/util/internal/error_listener.cc
new file mode 100644
index 0000000000..538307bae2
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/util/internal/error_listener.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/error_listener.h
new file mode 100644
index 0000000000..8c9c501682
--- /dev/null
+++ b/toolkit/components/protobuf/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_INTERNAL_ERROR_LISTENER_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_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/stubs/strutil.h>
+#include <google/protobuf/util/internal/location_tracker.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_INTERNAL_ERROR_LISTENER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/expecting_objectwriter.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/expecting_objectwriter.h
new file mode 100644
index 0000000000..76fe2b6049
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/expecting_objectwriter.h
@@ -0,0 +1,250 @@
+// 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_EXPECTING_OBJECTWRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_EXPECTING_OBJECTWRITER_H__
+
+// An implementation of ObjectWriter that automatically sets the
+// gmock expectations for the response to a method. Every method
+// returns the object itself for chaining.
+//
+// Usage:
+// // Setup
+// MockObjectWriter mock;
+// ExpectingObjectWriter ow(&mock);
+//
+// // Set expectation
+// ow.StartObject("")
+// ->RenderString("key", "value")
+// ->EndObject();
+//
+// // Actual testing
+// mock.StartObject(StringPiece())
+// ->RenderString("key", "value")
+// ->EndObject();
+
+#include <cstdint>
+
+#include <google/protobuf/stubs/common.h>
+#include <gmock/gmock.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/util/internal/object_writer.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+using testing::Eq;
+using testing::IsEmpty;
+using testing::NanSensitiveDoubleEq;
+using testing::NanSensitiveFloatEq;
+using testing::Return;
+using testing::StrEq;
+using testing::TypedEq;
+
+class MockObjectWriter : public ObjectWriter {
+ public:
+ MockObjectWriter() {}
+
+ MOCK_METHOD(ObjectWriter*, StartObject, (StringPiece), (override));
+ MOCK_METHOD(ObjectWriter*, EndObject, (), (override));
+ MOCK_METHOD(ObjectWriter*, StartList, (StringPiece), (override));
+ MOCK_METHOD(ObjectWriter*, EndList, (), (override));
+ MOCK_METHOD(ObjectWriter*, RenderBool, (StringPiece, bool), (override));
+ MOCK_METHOD(ObjectWriter*, RenderInt32, (StringPiece, int32_t),
+ (override));
+ MOCK_METHOD(ObjectWriter*, RenderUint32, (StringPiece, uint32_t),
+ (override));
+ MOCK_METHOD(ObjectWriter*, RenderInt64, (StringPiece, int64_t),
+ (override));
+ MOCK_METHOD(ObjectWriter*, RenderUint64, (StringPiece, uint64_t),
+ (override));
+ MOCK_METHOD(ObjectWriter*, RenderDouble, (StringPiece, double),
+ (override));
+ MOCK_METHOD(ObjectWriter*, RenderFloat, (StringPiece, float),
+ (override));
+ MOCK_METHOD(ObjectWriter*, RenderString,
+ (StringPiece, StringPiece), (override));
+ MOCK_METHOD(ObjectWriter*, RenderBytes, (StringPiece, StringPiece),
+ (override));
+ MOCK_METHOD(ObjectWriter*, RenderNull, (StringPiece), (override));
+};
+
+class ExpectingObjectWriter : public ObjectWriter {
+ public:
+ explicit ExpectingObjectWriter(MockObjectWriter* mock) : mock_(mock) {}
+
+ ObjectWriter* StartObject(StringPiece name) override {
+ (name.empty() ? EXPECT_CALL(*mock_, StartObject(IsEmpty()))
+ : EXPECT_CALL(*mock_, StartObject(Eq(std::string(name)))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ ObjectWriter* EndObject() override {
+ EXPECT_CALL(*mock_, EndObject())
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ ObjectWriter* StartList(StringPiece name) override {
+ (name.empty() ? EXPECT_CALL(*mock_, StartList(IsEmpty()))
+ : EXPECT_CALL(*mock_, StartList(Eq(std::string(name)))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ ObjectWriter* EndList() override {
+ EXPECT_CALL(*mock_, EndList())
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ ObjectWriter* RenderBool(StringPiece name, bool value) override {
+ (name.empty()
+ ? EXPECT_CALL(*mock_, RenderBool(IsEmpty(), TypedEq<bool>(value)))
+ : EXPECT_CALL(*mock_,
+ RenderBool(Eq(std::string(name)), TypedEq<bool>(value))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ ObjectWriter* RenderInt32(StringPiece name, int32_t value) override {
+ (name.empty()
+ ? EXPECT_CALL(*mock_, RenderInt32(IsEmpty(), TypedEq<int32_t>(value)))
+ : EXPECT_CALL(*mock_, RenderInt32(Eq(std::string(name)),
+ TypedEq<int32_t>(value))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ ObjectWriter* RenderUint32(StringPiece name, uint32_t value) override {
+ (name.empty() ? EXPECT_CALL(*mock_, RenderUint32(IsEmpty(),
+ TypedEq<uint32_t>(value)))
+ : EXPECT_CALL(*mock_, RenderUint32(Eq(std::string(name)),
+ TypedEq<uint32_t>(value))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ ObjectWriter* RenderInt64(StringPiece name, int64_t value) override {
+ (name.empty()
+ ? EXPECT_CALL(*mock_, RenderInt64(IsEmpty(), TypedEq<int64_t>(value)))
+ : EXPECT_CALL(*mock_, RenderInt64(Eq(std::string(name)),
+ TypedEq<int64_t>(value))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ ObjectWriter* RenderUint64(StringPiece name, uint64_t value) override {
+ (name.empty() ? EXPECT_CALL(*mock_, RenderUint64(IsEmpty(),
+ TypedEq<uint64_t>(value)))
+ : EXPECT_CALL(*mock_, RenderUint64(Eq(std::string(name)),
+ TypedEq<uint64_t>(value))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ ObjectWriter* RenderDouble(StringPiece name, double value) override {
+ (name.empty()
+ ? EXPECT_CALL(*mock_,
+ RenderDouble(IsEmpty(), NanSensitiveDoubleEq(value)))
+ : EXPECT_CALL(*mock_, RenderDouble(Eq(std::string(name)),
+ NanSensitiveDoubleEq(value))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ ObjectWriter* RenderFloat(StringPiece name, float value) override {
+ (name.empty()
+ ? EXPECT_CALL(*mock_,
+ RenderFloat(IsEmpty(), NanSensitiveFloatEq(value)))
+ : EXPECT_CALL(*mock_, RenderFloat(Eq(std::string(name)),
+ NanSensitiveFloatEq(value))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ ObjectWriter* RenderString(StringPiece name,
+ StringPiece value) override {
+ (name.empty() ? EXPECT_CALL(*mock_, RenderString(IsEmpty(),
+ TypedEq<StringPiece>(
+ std::string(value))))
+ : EXPECT_CALL(*mock_, RenderString(Eq(std::string(name)),
+ TypedEq<StringPiece>(
+ std::string(value)))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+ virtual ObjectWriter* RenderBytes(StringPiece name, StringPiece value) {
+ (name.empty()
+ ? EXPECT_CALL(*mock_, RenderBytes(IsEmpty(), TypedEq<StringPiece>(
+ value.ToString())))
+ : EXPECT_CALL(*mock_,
+ RenderBytes(Eq(std::string(name)),
+ TypedEq<StringPiece>(value.ToString()))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ ObjectWriter* RenderNull(StringPiece name) override {
+ (name.empty() ? EXPECT_CALL(*mock_, RenderNull(IsEmpty()))
+ : EXPECT_CALL(*mock_, RenderNull(Eq(std::string(name))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation());
+ return this;
+ }
+
+ private:
+ MockObjectWriter* mock_;
+
+ GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ExpectingObjectWriter);
+};
+
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_UTIL_INTERNAL_EXPECTING_OBJECTWRITER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/field_mask_utility.cc b/toolkit/components/protobuf/src/google/protobuf/util/internal/field_mask_utility.cc
new file mode 100644
index 0000000000..521bf48b7e
--- /dev/null
+++ b/toolkit/components/protobuf/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/stubs/status.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/util/internal/utility.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.
+std::string AppendPathSegmentToPrefix(StringPiece prefix,
+ StringPiece segment) {
+ if (prefix.empty()) {
+ return std::string(segment);
+ }
+ if (segment.empty()) {
+ return std::string(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
+
+std::string ConvertFieldMaskPath(const StringPiece path,
+ ConverterCallback converter) {
+ std::string 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<std::string> 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);
+ std::string 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/toolkit/components/protobuf/src/google/protobuf/util/internal/field_mask_utility.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/field_mask_utility.h
new file mode 100644
index 0000000000..1882333787
--- /dev/null
+++ b/toolkit/components/protobuf/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_INTERNAL_FIELD_MASK_UTILITY_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_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<std::string(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.
+std::string 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_INTERNAL_FIELD_MASK_UTILITY_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/json_escaping.cc b/toolkit/components/protobuf/src/google/protobuf/util/internal/json_escaping.cc
new file mode 100644
index 0000000000..e4fa8cf788
--- /dev/null
+++ b/toolkit/components/protobuf/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(uint32_t 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(uint32_t 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(uint32_t 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(uint32_t 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, uint32_t* 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()) {
+ uint32_t 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(uint32_t 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(uint32_t 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(uint32_t 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";
+ uint32_t 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/toolkit/components/protobuf/src/google/protobuf/util/internal/json_escaping.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/json_escaping.h
new file mode 100644
index 0000000000..7d54f22a38
--- /dev/null
+++ b/toolkit/components/protobuf/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 uint32_t kMinSupplementaryCodePoint = 0x010000;
+
+ // The minimum value of a unicode code point.
+ // See http://www.unicode.org/glossary/#code_point
+ static constexpr uint32_t kMinCodePoint = 0x000000;
+
+ // The maximum value of a unicode code point.
+ // See http://www.unicode.org/glossary/#code_point
+ static constexpr uint32_t 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/toolkit/components/protobuf/src/google/protobuf/util/internal/json_objectwriter.cc b/toolkit/components/protobuf/src/google/protobuf/util/internal/json_objectwriter.cc
new file mode 100644
index 0000000000..1a86f00533
--- /dev/null
+++ b/toolkit/components/protobuf/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/stubs/strutil.h>
+#include <google/protobuf/util/internal/json_escaping.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,
+ int32_t value) {
+ return RenderSimple(name, StrCat(value));
+}
+
+JsonObjectWriter* JsonObjectWriter::RenderUint32(StringPiece name,
+ uint32_t value) {
+ return RenderSimple(name, StrCat(value));
+}
+
+JsonObjectWriter* JsonObjectWriter::RenderInt64(StringPiece name,
+ int64_t value) {
+ WritePrefix(name);
+ WriteChar('"');
+ WriteRawString(StrCat(value));
+ WriteChar('"');
+ return this;
+}
+
+JsonObjectWriter* JsonObjectWriter::RenderUint64(StringPiece name,
+ uint64_t 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);
+ std::string base64;
+
+ if (use_websafe_base64_for_bytes_)
+ WebSafeBase64EscapeWithPadding(std::string(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/toolkit/components/protobuf/src/google/protobuf/util/internal/json_objectwriter.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/json_objectwriter.h
new file mode 100644
index 0000000000..cb7dff6e9f
--- /dev/null
+++ b/toolkit/components/protobuf/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_INTERNAL_JSON_OBJECTWRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_JSON_OBJECTWRITER_H__
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/stubs/bytestream.h>
+#include <google/protobuf/util/internal/structured_objectwriter.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;
+ }
+ }
+ }
+ }
+ ~JsonObjectWriter() override;
+
+ // 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, int32_t value) override;
+ JsonObjectWriter* RenderUint32(StringPiece name,
+ uint32_t value) override;
+ JsonObjectWriter* RenderInt64(StringPiece name, int64_t value) override;
+ JsonObjectWriter* RenderUint64(StringPiece name,
+ uint64_t 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 std::string 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_INTERNAL_JSON_OBJECTWRITER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/json_stream_parser.cc b/toolkit/components/protobuf/src/google/protobuf/util/internal/json_stream_parser.cc
new file mode 100644
index 0000000000..5c34dbccaf
--- /dev/null
+++ b/toolkit/components/protobuf/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 std::string& replacement,
+ std::string* 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<std::string> scratch;
+
+ bool is_valid_utf8 = internal::IsStructurallyValidUTF8(leftover_);
+ if (coerce_to_utf8_ && !is_valid_utf8) {
+ scratch.reset(new std::string);
+ 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_ = std::string(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_t 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_t 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 std::string& 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
+ std::string number = std::string(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_t.
+ 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_t.
+ 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);
+ std::string 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/toolkit/components/protobuf/src/google/protobuf/util/internal/json_stream_parser.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/json_stream_parser.h
new file mode 100644
index 0000000000..09f17ad085
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/json_stream_parser.h
@@ -0,0 +1,350 @@
+// 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_STREAM_PARSER_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_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>
+
+// Must be included last.
+#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;
+ int64_t int_val;
+ uint64_t 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 std::string& 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.
+ std::string 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.
+ std::string 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.
+ std::string 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().
+ std::string 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.
+ std::string 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_INTERNAL_JSON_STREAM_PARSER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/location_tracker.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/location_tracker.h
new file mode 100644
index 0000000000..68fefcc85c
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/location_tracker.h
@@ -0,0 +1,70 @@
+// 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_LOCATION_TRACKER_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_LOCATION_TRACKER_H__
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+// Must be included last.
+#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 std::string 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_INTERNAL_LOCATION_TRACKER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/mock_error_listener.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/mock_error_listener.h
new file mode 100644
index 0000000000..3fbdd883eb
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/mock_error_listener.h
@@ -0,0 +1,68 @@
+// 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_MOCK_ERROR_LISTENER_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_MOCK_ERROR_LISTENER_H__
+
+#include <gmock/gmock.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/util/internal/error_listener.h>
+#include <google/protobuf/util/internal/location_tracker.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+class MockErrorListener : public ErrorListener {
+ public:
+ MockErrorListener() {}
+ ~MockErrorListener() override {}
+
+ MOCK_METHOD(void, InvalidName,
+ (const LocationTrackerInterface& loc,
+ StringPiece unknown_name, StringPiece message),
+ (override));
+ MOCK_METHOD(void, InvalidValue,
+ (const LocationTrackerInterface& loc, StringPiece type_name,
+ StringPiece value),
+ (override));
+ MOCK_METHOD(void, MissingField,
+ (const LocationTrackerInterface& loc,
+ StringPiece missing_name),
+ (override));
+};
+
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_UTIL_INTERNAL_MOCK_ERROR_LISTENER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/object_location_tracker.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/object_location_tracker.h
new file mode 100644
index 0000000000..47821e6cb2
--- /dev/null
+++ b/toolkit/components/protobuf/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_INTERNAL_OBJECT_LOCATION_TRACKER_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_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.
+ std::string ToString() const override { return ""; }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjectLocationTracker);
+};
+
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_UTIL_INTERNAL_OBJECT_LOCATION_TRACKER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/object_source.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/object_source.h
new file mode 100644
index 0000000000..fc7672e5fa
--- /dev/null
+++ b/toolkit/components/protobuf/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_INTERNAL_OBJECT_SOURCE_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_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_INTERNAL_OBJECT_SOURCE_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/object_writer.cc b/toolkit/components/protobuf/src/google/protobuf/util/internal/object_writer.cc
new file mode 100644
index 0000000000..4dabd378e4
--- /dev/null
+++ b/toolkit/components/protobuf/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/toolkit/components/protobuf/src/google/protobuf/util/internal/object_writer.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/object_writer.h
new file mode 100644
index 0000000000..bc4095b6d4
--- /dev/null
+++ b/toolkit/components/protobuf/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_INTERNAL_OBJECT_WRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_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, int32_t value) = 0;
+
+ // Renders an 32-bit unsigned integer value.
+ virtual ObjectWriter* RenderUint32(StringPiece name,
+ uint32_t value) = 0;
+
+ // Renders a 64-bit integer value.
+ virtual ObjectWriter* RenderInt64(StringPiece name, int64_t value) = 0;
+
+ // Renders an 64-bit unsigned integer value.
+ virtual ObjectWriter* RenderUint64(StringPiece name,
+ uint64_t 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_INTERNAL_OBJECT_WRITER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/proto_writer.cc b/toolkit/components/protobuf/src/google/protobuf/util/internal/proto_writer.cc
new file mode 100644
index 0000000000..afa5e2e474
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/proto_writer.cc
@@ -0,0 +1,827 @@
+// 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 <unordered_set>
+
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/statusor.h>
+#include <google/protobuf/stubs/time.h>
+#include <google/protobuf/util/internal/constants.h>
+#include <google/protobuf/util/internal/field_mask_utility.h>
+#include <google/protobuf/util/internal/object_location_tracker.h>
+#include <google/protobuf/util/internal/utility.h>
+#include <google/protobuf/stubs/map_util.h>
+
+
+// Must be included last.
+#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<int32_t> 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<int32_t> 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<int32_t> 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<uint32_t> 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<uint32_t> 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<int64_t> 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<int64_t> 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<int64_t> 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<uint64_t> 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<uint64_t> 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<std::string> 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<std::string> 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::unordered_set<const google::protobuf::Field*> GetRequiredFields(
+ const google::protobuf::Type& type) {
+ std::unordered_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::unordered_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);
+ }
+}
+
+std::string ProtoWriter::ProtoElement::ToString() const {
+ std::string 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_) {
+ std::string 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(int32_t index) {
+ return oneof_indices_[index];
+}
+
+void ProtoWriter::ProtoElement::TakeOneofIndex(int32_t 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/toolkit/components/protobuf/src/google/protobuf/util/internal/proto_writer.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/proto_writer.h
new file mode 100644
index 0000000000..a7cf6acf78
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/proto_writer.h
@@ -0,0 +1,389 @@
+// 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_PROTO_WRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_PROTO_WRITER_H__
+
+#include <cstdint>
+#include <deque>
+#include <string>
+#include <unordered_set>
+#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/stubs/bytestream.h>
+#include <google/protobuf/stubs/status.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/internal/type_info.h>
+#include <google/protobuf/util/type_resolver.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, int32_t value) override {
+ return RenderDataPiece(name, DataPiece(value));
+ }
+ ProtoWriter* RenderUint32(StringPiece name, uint32_t value) override {
+ return RenderDataPiece(name, DataPiece(value));
+ }
+ ProtoWriter* RenderInt64(StringPiece name, int64_t value) override {
+ return RenderDataPiece(name, DataPiece(value));
+ }
+ ProtoWriter* RenderUint64(StringPiece name, uint64_t 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.
+ std::string 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(int32_t index);
+
+ // Marks the oneof 'index' as taken. Future inputs to this oneof will
+ // generate an error.
+ void TakeOneofIndex(int32_t 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::unordered_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_;
+ std::string 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_INTERNAL_PROTO_WRITER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectsource.cc b/toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectsource.cc
new file mode 100644
index 0000000000..cf6c99ac1f
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectsource.cc
@@ -0,0 +1,1114 @@
+// 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/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/stubs/strutil.h>
+#include <google/protobuf/stubs/casts.h>
+#include <google/protobuf/stubs/status.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/stubs/time.h>
+#include <google/protobuf/util/internal/constants.h>
+#include <google/protobuf/util/internal/field_mask_utility.h>
+#include <google/protobuf/util/internal/utility.h>
+#include <google/protobuf/stubs/map_util.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 {
+
+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 std::string FormatNanos(uint32_t nanos, bool with_trailing_zeros);
+
+util::StatusOr<std::string> MapKeyDefaultValueAsString(
+ const google::protobuf::Field& field) {
+ switch (field.kind()) {
+ case google::protobuf::Field::TYPE_BOOL:
+ return std::string("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 std::string("0");
+ case google::protobuf::Field::TYPE_STRING:
+ return std::string();
+ 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, uint32_t 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 uint32_t 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;
+ std::string field_name;
+ // last_tag set to dummy value that is different from tag.
+ uint32_t 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<uint32_t> ProtoStreamObjectSource::RenderList(
+ const google::protobuf::Field* field, StringPiece name,
+ uint32_t list_tag, ObjectWriter* ow) const {
+ uint32_t 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<uint32_t> ProtoStreamObjectSource::RenderMap(
+ const google::protobuf::Field* field, StringPiece /* name */,
+ uint32_t list_tag, ObjectWriter* ow) const {
+ const google::protobuf::Type* field_type =
+ typeinfo_->GetTypeByTypeUrl(field->type_url());
+ uint32_t tag_to_return = 0;
+ do {
+ // Render map entry message type.
+ uint32_t buffer32;
+ stream_->ReadVarint32(&buffer32); // message length
+ int old_limit = stream_->PushLimit(buffer32);
+ std::string map_key;
+ for (uint32_t 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 {
+ uint32_t 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<int64_t, int32_t> p = os->ReadSecondsAndNanos(type);
+ int64_t seconds = p.first;
+ int32_t 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<int64_t, int32_t> p = os->ReadSecondsAndNanos(type);
+ int64_t seconds = p.first;
+ int32_t 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));
+ }
+
+ std::string 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;
+ }
+ std::string 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) {
+ uint32_t tag = os->stream_->ReadTag();
+ uint64_t 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) {
+ uint32_t tag = os->stream_->ReadTag();
+ uint32_t 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) {
+ uint32_t tag = os->stream_->ReadTag();
+ uint64_t buffer64 = 0; // default value of Int64 wrapper value
+ if (tag != 0) {
+ os->stream_->ReadVarint64(&buffer64);
+ os->stream_->ReadTag();
+ }
+ ow->RenderInt64(field_name, bit_cast<int64_t>(buffer64));
+ return util::Status();
+}
+
+util::Status ProtoStreamObjectSource::RenderUInt64(
+ const ProtoStreamObjectSource* os, const google::protobuf::Type& /*type*/,
+ StringPiece field_name, ObjectWriter* ow) {
+ uint32_t tag = os->stream_->ReadTag();
+ uint64_t buffer64 = 0; // default value of UInt64 wrapper value
+ if (tag != 0) {
+ os->stream_->ReadVarint64(&buffer64);
+ os->stream_->ReadTag();
+ }
+ ow->RenderUint64(field_name, bit_cast<uint64_t>(buffer64));
+ return util::Status();
+}
+
+util::Status ProtoStreamObjectSource::RenderInt32(
+ const ProtoStreamObjectSource* os, const google::protobuf::Type& /*type*/,
+ StringPiece field_name, ObjectWriter* ow) {
+ uint32_t tag = os->stream_->ReadTag();
+ uint32_t buffer32 = 0; // default value of Int32 wrapper value
+ if (tag != 0) {
+ os->stream_->ReadVarint32(&buffer32);
+ os->stream_->ReadTag();
+ }
+ ow->RenderInt32(field_name, bit_cast<int32_t>(buffer32));
+ return util::Status();
+}
+
+util::Status ProtoStreamObjectSource::RenderUInt32(
+ const ProtoStreamObjectSource* os, const google::protobuf::Type& /*type*/,
+ StringPiece field_name, ObjectWriter* ow) {
+ uint32_t tag = os->stream_->ReadTag();
+ uint32_t buffer32 = 0; // default value of UInt32 wrapper value
+ if (tag != 0) {
+ os->stream_->ReadVarint32(&buffer32);
+ os->stream_->ReadTag();
+ }
+ ow->RenderUint32(field_name, bit_cast<uint32_t>(buffer32));
+ return util::Status();
+}
+
+util::Status ProtoStreamObjectSource::RenderBool(
+ const ProtoStreamObjectSource* os, const google::protobuf::Type& /*type*/,
+ StringPiece field_name, ObjectWriter* ow) {
+ uint32_t tag = os->stream_->ReadTag();
+ uint64_t 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) {
+ uint32_t tag = os->stream_->ReadTag();
+ uint32_t buffer32;
+ std::string 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) {
+ uint32_t tag = os->stream_->ReadTag();
+ uint32_t buffer32;
+ std::string 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;
+ uint32_t 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 (uint32_t 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) {
+ uint32_t 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; }
+ uint32_t tag;
+ std::string type_url;
+ std::string 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
+ uint32_t type_url_size;
+ os->stream_->ReadVarint32(&type_url_size);
+ os->stream_->ReadString(&type_url, type_url_size);
+ } else if (field->number() == 2) {
+ // read value
+ uint32_t 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) {
+ std::string combined;
+ uint32_t buffer32;
+ uint32_t paths_field_tag = 0;
+ for (uint32_t 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.");
+ }
+ std::string 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<std::string, ProtoStreamObjectSource::TypeRenderer>*
+ ProtoStreamObjectSource::renderers_ = nullptr;
+PROTOBUF_NAMESPACE_ID::internal::once_flag source_renderers_init_;
+
+
+void ProtoStreamObjectSource::InitRendererMap() {
+ renderers_ = new std::unordered_map<std::string,
+ 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 std::string& 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) {
+ uint32_t 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.
+ uint32_t buffer32 = 0;
+ uint64_t buffer64 = 0;
+ std::string 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<int32_t>(buffer32));
+ break;
+ }
+ case google::protobuf::Field::TYPE_INT64: {
+ stream_->ReadVarint64(&buffer64);
+ ow->RenderInt64(field_name, bit_cast<int64_t>(buffer64));
+ break;
+ }
+ case google::protobuf::Field::TYPE_UINT32: {
+ stream_->ReadVarint32(&buffer32);
+ ow->RenderUint32(field_name, bit_cast<uint32_t>(buffer32));
+ break;
+ }
+ case google::protobuf::Field::TYPE_UINT64: {
+ stream_->ReadVarint64(&buffer64);
+ ow->RenderUint64(field_name, bit_cast<uint64_t>(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<int32_t>(buffer32));
+ break;
+ }
+ case google::protobuf::Field::TYPE_SFIXED64: {
+ stream_->ReadLittleEndian64(&buffer64);
+ ow->RenderInt64(field_name, bit_cast<int64_t>(buffer64));
+ break;
+ }
+ case google::protobuf::Field::TYPE_FIXED32: {
+ stream_->ReadLittleEndian32(&buffer32);
+ ow->RenderUint32(field_name, bit_cast<uint32_t>(buffer32));
+ break;
+ }
+ case google::protobuf::Field::TYPE_FIXED64: {
+ stream_->ReadLittleEndian64(&buffer64);
+ ow->RenderUint64(field_name, bit_cast<uint64_t>(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 std::string ProtoStreamObjectSource::ReadFieldValueAsString(
+ const google::protobuf::Field& field) const {
+ std::string result;
+ switch (field.kind()) {
+ case google::protobuf::Field::TYPE_BOOL: {
+ uint64_t buffer64;
+ stream_->ReadVarint64(&buffer64);
+ result = buffer64 != 0 ? "true" : "false";
+ break;
+ }
+ case google::protobuf::Field::TYPE_INT32: {
+ uint32_t buffer32;
+ stream_->ReadVarint32(&buffer32);
+ result = StrCat(bit_cast<int32_t>(buffer32));
+ break;
+ }
+ case google::protobuf::Field::TYPE_INT64: {
+ uint64_t buffer64;
+ stream_->ReadVarint64(&buffer64);
+ result = StrCat(bit_cast<int64_t>(buffer64));
+ break;
+ }
+ case google::protobuf::Field::TYPE_UINT32: {
+ uint32_t buffer32;
+ stream_->ReadVarint32(&buffer32);
+ result = StrCat(bit_cast<uint32_t>(buffer32));
+ break;
+ }
+ case google::protobuf::Field::TYPE_UINT64: {
+ uint64_t buffer64;
+ stream_->ReadVarint64(&buffer64);
+ result = StrCat(bit_cast<uint64_t>(buffer64));
+ break;
+ }
+ case google::protobuf::Field::TYPE_SINT32: {
+ uint32_t buffer32;
+ stream_->ReadVarint32(&buffer32);
+ result = StrCat(WireFormatLite::ZigZagDecode32(buffer32));
+ break;
+ }
+ case google::protobuf::Field::TYPE_SINT64: {
+ uint64_t buffer64;
+ stream_->ReadVarint64(&buffer64);
+ result = StrCat(WireFormatLite::ZigZagDecode64(buffer64));
+ break;
+ }
+ case google::protobuf::Field::TYPE_SFIXED32: {
+ uint32_t buffer32;
+ stream_->ReadLittleEndian32(&buffer32);
+ result = StrCat(bit_cast<int32_t>(buffer32));
+ break;
+ }
+ case google::protobuf::Field::TYPE_SFIXED64: {
+ uint64_t buffer64;
+ stream_->ReadLittleEndian64(&buffer64);
+ result = StrCat(bit_cast<int64_t>(buffer64));
+ break;
+ }
+ case google::protobuf::Field::TYPE_FIXED32: {
+ uint32_t buffer32;
+ stream_->ReadLittleEndian32(&buffer32);
+ result = StrCat(bit_cast<uint32_t>(buffer32));
+ break;
+ }
+ case google::protobuf::Field::TYPE_FIXED64: {
+ uint64_t buffer64;
+ stream_->ReadLittleEndian64(&buffer64);
+ result = StrCat(bit_cast<uint64_t>(buffer64));
+ break;
+ }
+ case google::protobuf::Field::TYPE_FLOAT: {
+ uint32_t buffer32;
+ stream_->ReadLittleEndian32(&buffer32);
+ result = SimpleFtoa(bit_cast<float>(buffer32));
+ break;
+ }
+ case google::protobuf::Field::TYPE_DOUBLE: {
+ uint64_t buffer64;
+ stream_->ReadLittleEndian64(&buffer64);
+ result = SimpleDtoa(bit_cast<double>(buffer64));
+ break;
+ }
+ case google::protobuf::Field::TYPE_ENUM: {
+ uint32_t 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: {
+ uint32_t buffer32;
+ stream_->ReadVarint32(&buffer32); // string size.
+ stream_->ReadString(&result, buffer32);
+ break;
+ }
+ case google::protobuf::Field::TYPE_BYTES: {
+ uint32_t 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<int64_t, int32_t> ProtoStreamObjectSource::ReadSecondsAndNanos(
+ const google::protobuf::Type& type) const {
+ uint64_t seconds = 0;
+ uint32_t nanos = 0;
+ uint32_t tag = 0;
+ int64_t signed_seconds = 0;
+ int32_t 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<int64_t>(seconds);
+ } else if (field->number() == 2) {
+ // read nanos
+ stream_->ReadVarint32(&nanos);
+ signed_nanos = bit_cast<int32_t>(nanos);
+ }
+ }
+ return std::pair<int64_t, int32_t>(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 std::string FormatNanos(uint32_t nanos, bool with_trailing_zeros) {
+ if (nanos == 0) {
+ return with_trailing_zeros ? ".000" : "";
+ }
+
+ const int precision = (nanos % 1000 != 0) ? 9
+ : (nanos % 1000000 != 0) ? 6
+ : 3;
+ std::string formatted = StringPrintf(
+ "%.*f", precision, 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/toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectsource.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectsource.h
new file mode 100644
index 0000000000..8ed2ca9bb4
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectsource.h
@@ -0,0 +1,329 @@
+// 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_PROTOSTREAM_OBJECTSOURCE_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_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/stubs/statusor.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/util/internal/object_source.h>
+#include <google/protobuf/util/internal/object_writer.h>
+#include <google/protobuf/util/internal/type_info.h>
+#include <google/protobuf/util/type_resolver.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 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 uint32_t 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<uint32_t> RenderList(
+ const google::protobuf::Field* field, StringPiece name,
+ uint32_t 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, uint32_t 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 std::string 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<uint32_t> RenderMap(const google::protobuf::Field* field,
+ StringPiece name, uint32_t 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<std::string, TypeRenderer>* renderers_;
+ static void InitRendererMap();
+ static void DeleteRendererMap();
+ static TypeRenderer* FindTypeRenderer(const std::string& 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<int64_t, int32_t> 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_INTERNAL_PROTOSTREAM_OBJECTSOURCE_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectwriter.cc b/toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectwriter.cc
new file mode 100644
index 0000000000..ecb219e06e
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -0,0 +1,1401 @@
+// 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/stubs/strutil.h>
+#include <google/protobuf/stubs/status.h>
+#include <google/protobuf/stubs/statusor.h>
+#include <google/protobuf/stubs/time.h>
+#include <google/protobuf/util/internal/constants.h>
+#include <google/protobuf/util/internal/field_mask_utility.h>
+#include <google/protobuf/util/internal/object_location_tracker.h>
+#include <google/protobuf/util/internal/utility.h>
+#include <google/protobuf/stubs/map_util.h>
+
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+using util::Status;
+using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
+using std::placeholders::_1;
+
+
+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 != std::string::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,
+ int32_t* 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++;
+ }
+ int32_t i_nanos = 0;
+ // 's_nanos' contains fractional seconds -- i.e. 'nanos' is equal to
+ // "0." + s_nanos.ToString() seconds. An int32_t 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()
+ int32_t scale = num_leading_zeros + s_nanos.size();
+ // 'conversion' converts i_nanos into nanoseconds.
+ // conversion = kNanosPerSecond / static_cast<int32_t>(std::pow(10, scale))
+ // For efficiency, we precompute the conversion factor.
+ int32_t 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_ = std::string(value.str());
+ } else {
+ util::StatusOr<std::string> 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<std::string>);
+ }
+}
+
+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<std::string>);
+ }
+}
+
+bool ProtoStreamObjectWriter::Item::InsertMapKeyIfNotPresent(
+ StringPiece map_key) {
+ return InsertIfNotPresent(map_keys_.get(), std::string(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/main/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/main/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/main/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) {
+ std::string struct_field_name;
+ switch (data.type()) {
+ case DataPiece::TYPE_INT32: {
+ if (ow->options_.struct_integers_as_strings) {
+ util::StatusOr<int32_t> 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<uint32_t> 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<int64_t> 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<uint64_t> 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_t seconds;
+ int32_t 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);
+ uint64_t unsigned_seconds;
+ if (!safe_strtou64(s_secs, &unsigned_seconds)) {
+ return util::InvalidArgumentError(
+ "Invalid duration format, failed to parse seconds");
+ }
+
+ int32_t 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;
+
+ int64_t 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<std::string, ProtoStreamObjectWriter::TypeRenderer>*
+ ProtoStreamObjectWriter::renderers_ = nullptr;
+PROTOBUF_NAMESPACE_ID::internal::once_flag writer_renderers_init_;
+
+void ProtoStreamObjectWriter::InitRendererMap() {
+ renderers_ = new std::unordered_map<std::string,
+ 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 std::string& 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/toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectwriter.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectwriter.h
new file mode 100644
index 0000000000..ce2517f9e9
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/protostream_objectwriter.h
@@ -0,0 +1,453 @@
+// 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_PROTOSTREAM_OBJECTWRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_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/stubs/bytestream.h>
+#include <google/protobuf/stubs/status.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/internal/type_info.h>
+#include <google/protobuf/util/type_resolver.h>
+#include <google/protobuf/stubs/hash.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 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_;
+ std::string name_;
+ DataPiece value_;
+ std::string 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.
+ std::string 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.
+ std::string 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<std::string> > 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 std::string& 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<std::string, 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_INTERNAL_PROTOSTREAM_OBJECTWRITER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/structured_objectwriter.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/structured_objectwriter.h
new file mode 100644
index 0000000000..f6f7c89e57
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/structured_objectwriter.h
@@ -0,0 +1,121 @@
+// 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_STRUCTURED_OBJECTWRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_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>
+
+// Must be included last.
+#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:
+ ~StructuredObjectWriter() override {}
+
+ 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_INTERNAL_STRUCTURED_OBJECTWRITER_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/type_info.cc b/toolkit/components/protobuf/src/google/protobuf/util/internal/type_info.cc
new file mode 100644
index 0000000000..b6cf5366ae
--- /dev/null
+++ b/toolkit/components/protobuf/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/stubs/status.h>
+#include <google/protobuf/stubs/statusor.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/util/internal/utility.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) {}
+
+ ~TypeInfoForTypeResolver() override {
+ 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 std::string& string_type_url =
+ *string_storage_.insert(std::string(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 std::string& string_type_url =
+ *string_storage_.insert(std::string(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<std::string> 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/toolkit/components/protobuf/src/google/protobuf/util/internal/type_info.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/type_info.h
new file mode 100644
index 0000000000..257df5bad6
--- /dev/null
+++ b/toolkit/components/protobuf/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_INTERNAL_TYPE_INFO_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_TYPE_INFO_H__
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/type.pb.h>
+#include <google/protobuf/stubs/statusor.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/util/type_resolver.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_INTERNAL_TYPE_INFO_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/internal/utility.cc b/toolkit/components/protobuf/src/google/protobuf/util/internal/utility.cc
new file mode 100644
index 0000000000..918ee17d9b
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/internal/utility.cc
@@ -0,0 +1,416 @@
+// 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/stubs/strutil.h>
+#include <google/protobuf/util/internal/constants.h>
+#include <google/protobuf/stubs/map_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());
+}
+
+int64_t GetInt64OptionOrDefault(
+ const RepeatedPtrField<google::protobuf::Option>& options,
+ StringPiece option_name, int64_t 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());
+}
+
+std::string 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 std::string(default_value);
+ }
+ return GetStringFromAny(opt->value());
+}
+
+template <typename T>
+void ParseFromAny(const std::string& 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();
+}
+
+int64_t 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();
+}
+
+std::string 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 std::string 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, int32_t 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, int32_t 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);
+ std::string enum_name_without_underscore = enum_value.name();
+
+ // Remove underscore from the name.
+ enum_name_without_underscore.erase(
+ std::remove(enum_name_without_underscore.begin(),
+ enum_name_without_underscore.end(), '_'),
+ enum_name_without_underscore.end());
+ // Make the name uppercase.
+ for (std::string::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;
+}
+
+std::string EnumValueNameToLowerCamelCase(StringPiece input) {
+ std::string input_string(input);
+ std::transform(input_string.begin(), input_string.end(), input_string.begin(),
+ ::tolower);
+ return ToCamelCase(input_string);
+}
+
+std::string ToCamelCase(StringPiece input) {
+ bool capitalize_next = false;
+ bool was_cap = true;
+ bool is_cap = false;
+ bool first_word = true;
+ std::string 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;
+}
+
+std::string ToSnakeCase(StringPiece input) {
+ bool was_not_underscore = false; // Initialize to false for case 1 (below)
+ bool was_not_cap = false;
+ std::string 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<std::string>* 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<std::string>;
+ 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 std::string& 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);
+}
+
+std::string 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);
+}
+
+std::string 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/toolkit/components/protobuf/src/google/protobuf/util/internal/utility.h b/toolkit/components/protobuf/src/google/protobuf/util/internal/utility.h
new file mode 100644
index 0000000000..79d6779735
--- /dev/null
+++ b/toolkit/components/protobuf/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_INTERNAL_UTILITY_H__
+#define GOOGLE_PROTOBUF_UTIL_INTERNAL_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 int64_t 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 int64_t GetInt64OptionOrDefault(
+ const RepeatedPtrField<google::protobuf::Option>& options,
+ StringPiece option_name, int64_t 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 std::string 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 int64_t 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 std::string 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 std::string 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, int32_t 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, int32_t 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 std::string ToCamelCase(const StringPiece input);
+
+// Converts enum name string to camel-case and returns it.
+std::string EnumValueNameToLowerCamelCase(const StringPiece input);
+
+// Converts input to snake_case and returns it.
+PROTOBUF_EXPORT std::string ToSnakeCase(StringPiece input);
+
+// Returns true if type_name represents a well-known type.
+PROTOBUF_EXPORT bool IsWellKnownType(const std::string& 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 std::string DoubleAsString(double value);
+PROTOBUF_EXPORT std::string FloatAsString(float value);
+
+// Convert from int32, int64, uint32, uint64, double or float to string.
+template <typename T>
+std::string ValueAsString(T value) {
+ return StrCat(value);
+}
+
+template <>
+inline std::string ValueAsString(float value) {
+ return FloatAsString(value);
+}
+
+template <>
+inline std::string 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_INTERNAL_UTILITY_H__
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/json_format.proto b/toolkit/components/protobuf/src/google/protobuf/util/json_format.proto
new file mode 100644
index 0000000000..7b7100d788
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/json_format.proto
@@ -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: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file we will use for unit testing.
+
+syntax = "proto2";
+
+package protobuf_unittest;
+
+message TestFlagsAndStrings {
+ required int32 A = 1;
+ repeated group RepeatedGroup = 2 {
+ required string f = 3;
+ }
+}
+
+message TestBase64ByteArrays {
+ required bytes a = 1;
+}
+
+message TestJavaScriptJSON {
+ optional int32 a = 1;
+ optional float final = 2;
+ optional string in = 3;
+ optional string Var = 4;
+}
+
+message TestJavaScriptOrderJSON1 {
+ optional int32 d = 1;
+ optional int32 c = 2;
+ optional bool x = 3;
+ optional int32 b = 4;
+ optional int32 a = 5;
+}
+
+message TestJavaScriptOrderJSON2 {
+ optional int32 d = 1;
+ optional int32 c = 2;
+ optional bool x = 3;
+ optional int32 b = 4;
+ optional int32 a = 5;
+ repeated TestJavaScriptOrderJSON1 z = 6;
+}
+
+message TestLargeInt {
+ required int64 a = 1;
+ required uint64 b = 2;
+}
+
+message TestNumbers {
+ enum MyType {
+ OK = 0;
+ WARNING = 1;
+ ERROR = 2;
+ }
+ optional MyType a = 1;
+ optional int32 b = 2;
+ optional float c = 3;
+ optional bool d = 4;
+ optional double e = 5;
+ optional uint32 f = 6;
+}
+
+
+message TestCamelCase {
+ optional string normal_field = 1;
+ optional int32 CAPITAL_FIELD = 2;
+ optional int32 CamelCaseField = 3;
+}
+
+message TestBoolMap {
+ map<bool, int32> bool_map = 1;
+}
+
+message TestRecursion {
+ optional int32 value = 1;
+ optional TestRecursion child = 2;
+}
+
+message TestStringMap {
+ map<string, string> string_map = 1;
+}
+
+message TestStringSerializer {
+ optional string scalar_string = 1;
+ repeated string repeated_string = 2;
+ map<string, string> string_map = 3;
+}
+
+message TestMessageWithExtension {
+ extensions 100 to max;
+}
+
+message TestExtension {
+ extend TestMessageWithExtension {
+ optional TestExtension ext = 100;
+ }
+ optional string value = 1;
+}
+
+enum EnumValue {
+ PROTOCOL = 0;
+ BUFFER = 1;
+ DEFAULT = 2;
+}
+
+message TestDefaultEnumValue {
+ optional EnumValue enum_value = 1 [default = DEFAULT];
+}
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/json_format_proto3.proto b/toolkit/components/protobuf/src/google/protobuf/util/json_format_proto3.proto
new file mode 100644
index 0000000000..0eec9da319
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/json_format_proto3.proto
@@ -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.
+
+syntax = "proto3";
+
+package proto3;
+
+import "google/protobuf/any.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/wrappers.proto";
+import "google/protobuf/unittest.proto";
+
+option java_package = "com.google.protobuf.util";
+option java_outer_classname = "JsonFormatProto3";
+
+enum EnumType {
+ FOO = 0;
+ BAR = 1;
+}
+
+message MessageType {
+ int32 value = 1;
+}
+
+message TestMessage {
+ bool bool_value = 1;
+ int32 int32_value = 2;
+ int64 int64_value = 3;
+ uint32 uint32_value = 4;
+ uint64 uint64_value = 5;
+ float float_value = 6;
+ double double_value = 7;
+ string string_value = 8;
+ bytes bytes_value = 9;
+ EnumType enum_value = 10;
+ MessageType message_value = 11;
+
+ repeated bool repeated_bool_value = 21;
+ repeated int32 repeated_int32_value = 22;
+ repeated int64 repeated_int64_value = 23;
+ repeated uint32 repeated_uint32_value = 24;
+ repeated uint64 repeated_uint64_value = 25;
+ repeated float repeated_float_value = 26;
+ repeated double repeated_double_value = 27;
+ repeated string repeated_string_value = 28;
+ repeated bytes repeated_bytes_value = 29;
+ repeated EnumType repeated_enum_value = 30;
+ repeated MessageType repeated_message_value = 31;
+}
+
+message TestOneof {
+ // In JSON format oneof fields behave mostly the same as optional
+ // fields except that:
+ // 1. Oneof fields have field presence information and will be
+ // printed if it's set no matter whether it's the default value.
+ // 2. Multiple oneof fields in the same oneof cannot appear at the
+ // same time in the input.
+ oneof oneof_value {
+ int32 oneof_int32_value = 1;
+ string oneof_string_value = 2;
+ bytes oneof_bytes_value = 3;
+ EnumType oneof_enum_value = 4;
+ MessageType oneof_message_value = 5;
+ google.protobuf.NullValue oneof_null_value = 6;
+ }
+}
+
+message TestMap {
+ map<bool, int32> bool_map = 1;
+ map<int32, int32> int32_map = 2;
+ map<int64, int32> int64_map = 3;
+ map<uint32, int32> uint32_map = 4;
+ map<uint64, int32> uint64_map = 5;
+ map<string, int32> string_map = 6;
+}
+
+message TestNestedMap {
+ map<bool, int32> bool_map = 1;
+ map<int32, int32> int32_map = 2;
+ map<int64, int32> int64_map = 3;
+ map<uint32, int32> uint32_map = 4;
+ map<uint64, int32> uint64_map = 5;
+ map<string, int32> string_map = 6;
+ map<string, TestNestedMap> map_map = 7;
+}
+
+message TestStringMap {
+ map<string, string> string_map = 1;
+}
+
+message TestWrapper {
+ google.protobuf.BoolValue bool_value = 1;
+ google.protobuf.Int32Value int32_value = 2;
+ google.protobuf.Int64Value int64_value = 3;
+ google.protobuf.UInt32Value uint32_value = 4;
+ google.protobuf.UInt64Value uint64_value = 5;
+ google.protobuf.FloatValue float_value = 6;
+ google.protobuf.DoubleValue double_value = 7;
+ google.protobuf.StringValue string_value = 8;
+ google.protobuf.BytesValue bytes_value = 9;
+
+ repeated google.protobuf.BoolValue repeated_bool_value = 11;
+ repeated google.protobuf.Int32Value repeated_int32_value = 12;
+ repeated google.protobuf.Int64Value repeated_int64_value = 13;
+ repeated google.protobuf.UInt32Value repeated_uint32_value = 14;
+ repeated google.protobuf.UInt64Value repeated_uint64_value = 15;
+ repeated google.protobuf.FloatValue repeated_float_value = 16;
+ repeated google.protobuf.DoubleValue repeated_double_value = 17;
+ repeated google.protobuf.StringValue repeated_string_value = 18;
+ repeated google.protobuf.BytesValue repeated_bytes_value = 19;
+}
+
+message TestTimestamp {
+ google.protobuf.Timestamp value = 1;
+ repeated google.protobuf.Timestamp repeated_value = 2;
+}
+
+message TestDuration {
+ google.protobuf.Duration value = 1;
+ repeated google.protobuf.Duration repeated_value = 2;
+}
+
+message TestFieldMask {
+ google.protobuf.FieldMask value = 1;
+}
+
+message TestStruct {
+ google.protobuf.Struct value = 1;
+ repeated google.protobuf.Struct repeated_value = 2;
+}
+
+message TestAny {
+ google.protobuf.Any value = 1;
+ repeated google.protobuf.Any repeated_value = 2;
+}
+
+message TestValue {
+ google.protobuf.Value value = 1;
+ repeated google.protobuf.Value repeated_value = 2;
+}
+
+message TestListValue {
+ google.protobuf.ListValue value = 1;
+ repeated google.protobuf.ListValue repeated_value = 2;
+}
+
+message TestBoolValue {
+ bool bool_value = 1;
+ map<bool, int32> bool_map = 2;
+}
+
+message TestCustomJsonName {
+ int32 value = 1 [json_name = "@value"];
+}
+
+message TestExtensions {
+ .protobuf_unittest.TestAllExtensions extensions = 1;
+}
+
+message TestEnumValue {
+ EnumType enum_value1 = 1;
+ EnumType enum_value2 = 2;
+ EnumType enum_value3 = 3;
+}
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/json_util.cc b/toolkit/components/protobuf/src/google/protobuf/util/json_util.cc
new file mode 100644
index 0000000000..c39c10d87b
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/json_util.cc
@@ -0,0 +1,284 @@
+// 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/stubs/once.h>
+#include <google/protobuf/stubs/status.h>
+#include <google/protobuf/stubs/bytestream.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.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/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_) { // NOLINT
+ 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 std::string& 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 std::string& type_url,
+ const std::string& binary_input,
+ std::string* 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 {
+ std::string 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 ", std::string(value),
+ " for type ", std::string(type_name)));
+ }
+
+ void MissingField(const converter::LocationTrackerInterface& loc,
+ StringPiece missing_name) override {
+ status_ = util::InvalidArgumentError(StrCat(
+ GetLocString(loc), ": missing field ", std::string(missing_name)));
+ }
+
+ private:
+ util::Status status_;
+
+ std::string GetLocString(const converter::LocationTrackerInterface& loc) {
+ std::string 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 std::string& 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 std::string& type_url,
+ StringPiece json_input,
+ std::string* 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_ = nullptr;
+PROTOBUF_NAMESPACE_ID::internal::once_flag generated_type_resolver_init_;
+
+std::string GetTypeUrl(const Message& message) {
+ return std::string(kTypeUrlPrefix) + "/" +
+ message.GetDescriptor()->full_name();
+}
+
+void DeleteGeneratedTypeResolver() { // NOLINT
+ 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, std::string* 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);
+ std::string 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/toolkit/components/protobuf/src/google/protobuf/util/json_util.h b/toolkit/components/protobuf/src/google/protobuf/util/json_util.h
new file mode 100644
index 0000000000..0f1c4d8b5f
--- /dev/null
+++ b/toolkit/components/protobuf/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/stubs/bytestream.h>
+#include <google/protobuf/stubs/status.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/util/type_resolver.h>
+
+// Must be included last.
+#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,
+ std::string* output,
+ const JsonOptions& options);
+
+inline util::Status MessageToJsonString(const Message& message,
+ std::string* 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 std::string& type_url,
+ io::ZeroCopyInputStream* binary_input,
+ io::ZeroCopyOutputStream* json_output, const JsonPrintOptions& options);
+
+inline util::Status BinaryToJsonStream(TypeResolver* resolver,
+ const std::string& 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 std::string& type_url,
+ const std::string& binary_input, std::string* json_output,
+ const JsonPrintOptions& options);
+
+inline util::Status BinaryToJsonString(TypeResolver* resolver,
+ const std::string& type_url,
+ const std::string& binary_input,
+ std::string* 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 std::string& type_url,
+ io::ZeroCopyInputStream* json_input,
+ io::ZeroCopyOutputStream* binary_output, const JsonParseOptions& options);
+
+inline util::Status JsonToBinaryStream(
+ TypeResolver* resolver, const std::string& 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 std::string& type_url,
+ StringPiece json_input, std::string* binary_output,
+ const JsonParseOptions& options);
+
+inline util::Status JsonToBinaryString(TypeResolver* resolver,
+ const std::string& type_url,
+ StringPiece json_input,
+ std::string* 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_(nullptr), buffer_size_(0) {}
+ ~ZeroCopyStreamByteSink() override;
+
+ 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/toolkit/components/protobuf/src/google/protobuf/util/message_differencer.cc b/toolkit/components/protobuf/src/google/protobuf/util/message_differencer.cc
new file mode 100644
index 0000000000..30560ed5f4
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/message_differencer.cc
@@ -0,0 +1,2246 @@
+// 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/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/stubs/strutil.h>
+#include <google/protobuf/stubs/stringprintf.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 {
+
+namespace util {
+
+namespace {
+
+std::string PrintShortTextFormat(const google::protobuf::Message& message) {
+ std::string debug_string;
+
+ google::protobuf::TextFormat::Printer printer;
+ printer.SetSingleLineMode(true);
+ printer.SetExpandAny(true);
+
+ printer.PrintToString(message, &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;
+}
+
+} // namespace
+
+// 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.
+ int32_t 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:
+ int32_t 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<int64_t>(key_field_path.size() - 1)) {
+ if (field->is_map()) {
+ return message_differencer_->CompareMapField(message1, message2, field,
+ &current_parent_fields);
+ } else if (field->is_repeated()) {
+ return message_differencer_->CompareRepeatedField(
+ message1, message2, field, &current_parent_fields);
+ } else {
+ return message_differencer_->CompareFieldValueUsingParentFields(
+ message1, message2, field, -1, -1, &current_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,
+ &current_parent_fields);
+ }
+ return message_differencer_->CompareFieldValueUsingParentFields(
+ message1, message2, key, -1, -1, &current_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;
+}
+
+MessageDifferencer::MessageFieldComparison
+MessageDifferencer::message_field_comparison() const {
+ return message_field_comparison_;
+}
+
+void MessageDifferencer::set_scope(Scope scope) { scope_ = scope; }
+
+MessageDifferencer::Scope MessageDifferencer::scope() const { 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() const {
+ 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(std::string* 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,
+ &current_parent_fields);
+ }
+ // Back up the Reporter and output_string_. They will be reset in the
+ // following code.
+ Reporter* backup_reporter = reporter_;
+ std::string* output_string = output_string_;
+ reporter_ = reporter;
+ output_string_ = NULL;
+ bool match;
+
+ if (key_comparator == NULL) {
+ match = CompareFieldValueUsingParentFields(*message1, *message2,
+ repeated_field, index1, index2,
+ &current_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,
+ &current_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 std::string& type_url = reflection->GetString(any, type_url_field);
+ std::string 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());
+ std::string 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<int32_t> num_diffs_list1;
+ if (is_treated_as_smart_set) {
+ num_diffs_list1.assign(count1, std::numeric_limits<int32_t>::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 int32_t 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) {
+ std::string 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 = PrintShortTextFormat(
+ field_message.GetReflection()->GetMessage(field_message, fd));
+ } else {
+ TextFormat::PrintFieldValueToString(field_message, fd, -1, &output);
+ }
+ } else {
+ output = PrintShortTextFormat(field_message);
+ }
+ 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.";
+
+ std::string 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 std::string& 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;
+ std::string 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/toolkit/components/protobuf/src/google/protobuf/util/message_differencer.h b/toolkit/components/protobuf/src/google/protobuf/util/message_differencer.h
new file mode 100644
index 0000000000..f63cd54185
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/message_differencer.h
@@ -0,0 +1,980 @@
+// 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 mooo are changed.
+ // foo {
+ // bar {
+ // baz: 1
+ // mooo: 2
+ // }
+ // }
+ // ReportModified will be invoked with following order:
+ // 1. foo.bar.baz or foo.bar.mooo
+ // 2. foo.bar.mooo 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);
+
+ // Returns the current message field comparison used in this differencer.
+ MessageFieldComparison message_field_comparison() const;
+
+ // 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() const;
+
+ // 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() const;
+
+ // 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(std::string* 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 std::string& 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_;
+
+ std::string* 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/toolkit/components/protobuf/src/google/protobuf/util/package_info.h b/toolkit/components/protobuf/src/google/protobuf/util/package_info.h
new file mode 100644
index 0000000000..96019203bc
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/package_info.h
@@ -0,0 +1,46 @@
+// 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 exists solely to document the google::protobuf::util namespace.
+// It is not compiled into anything, but it may be read by an automated
+// documentation generator.
+
+namespace google {
+
+namespace protobuf {
+
+// Utility classes.
+//
+// This package contains various utilities for message comparison, JSON
+// conversion, well known types, etc.
+namespace util {}
+
+} // namespace protobuf
+} // namespace google
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/time_util.cc b/toolkit/components/protobuf/src/google/protobuf/util/time_util.cc
new file mode 100644
index 0000000000..9893aa35df
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/time_util.cc
@@ -0,0 +1,514 @@
+// 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/strutil.h>
+#include <google/protobuf/duration.pb.h>
+#include <google/protobuf/timestamp.pb.h>
+#include <google/protobuf/stubs/int128.h>
+#include <google/protobuf/stubs/stringprintf.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(int64_t seconds, int64_t nanos);
+
+template <>
+Timestamp CreateNormalized(int64_t seconds, int64_t 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<int32_t>(nanos));
+ return result;
+}
+
+template <>
+Duration CreateNormalized(int64_t seconds, int64_t 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<int32_t>(nanos));
+ return result;
+}
+
+// Format nanoseconds with either 3, 6, or 9 digits depending on the required
+// precision to represent the exact value.
+std::string FormatNanos(int32_t 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);
+ }
+}
+
+std::string FormatTime(int64_t seconds, int32_t nanos) {
+ return ::google::protobuf::internal::FormatTime(seconds, nanos);
+}
+
+bool ParseTime(const std::string& value, int64_t* seconds, int32_t* nanos) {
+ return ::google::protobuf::internal::ParseTime(value, seconds, nanos);
+}
+
+void CurrentTime(int64_t* seconds, int32_t* nanos) {
+ return ::google::protobuf::internal::GetCurrentTime(seconds, nanos);
+}
+
+// Truncates the remainder part after division.
+int64_t RoundTowardZero(int64_t value, int64_t divider) {
+ int64_t result = value / divider;
+ int64_t 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 int64_t TimeUtil::kTimestampMinSeconds;
+const int64_t TimeUtil::kTimestampMaxSeconds;
+const int64_t TimeUtil::kDurationMaxSeconds;
+const int64_t TimeUtil::kDurationMinSeconds;
+#endif // !_MSC_VER
+
+std::string TimeUtil::ToString(const Timestamp& timestamp) {
+ return FormatTime(timestamp.seconds(), timestamp.nanos());
+}
+
+bool TimeUtil::FromString(const std::string& value, Timestamp* timestamp) {
+ int64_t seconds;
+ int32_t nanos;
+ if (!ParseTime(value, &seconds, &nanos)) {
+ return false;
+ }
+ *timestamp = CreateNormalized<Timestamp>(seconds, nanos);
+ return true;
+}
+
+Timestamp TimeUtil::GetCurrentTime() {
+ int64_t seconds;
+ int32_t nanos;
+ CurrentTime(&seconds, &nanos);
+ return CreateNormalized<Timestamp>(seconds, nanos);
+}
+
+Timestamp TimeUtil::GetEpoch() { return Timestamp(); }
+
+std::string TimeUtil::ToString(const Duration& duration) {
+ std::string result;
+ int64_t seconds = duration.seconds();
+ int32_t 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 int64_t Pow(int64_t x, int y) {
+ int64_t result = 1;
+ for (int i = 0; i < y; ++i) {
+ result *= x;
+ }
+ return result;
+}
+
+bool TimeUtil::FromString(const std::string& value, Duration* duration) {
+ if (value.length() <= 1 || value[value.length() - 1] != 's') {
+ return false;
+ }
+ bool negative = (value[0] == '-');
+ size_t sign_length = (negative ? 1 : 0);
+ // Parse the duration value as two integers rather than a float value
+ // to avoid precision loss.
+ std::string seconds_part, nanos_part;
+ size_t pos = value.find_last_of('.');
+ if (pos == std::string::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;
+ int64_t seconds = strto64(seconds_part.c_str(), &end, 10);
+ if (end != seconds_part.c_str() + seconds_part.length()) {
+ return false;
+ }
+ int64_t nanos = strto64(nanos_part.c_str(), &end, 10);
+ if (end != nanos_part.c_str() + nanos_part.length()) {
+ return false;
+ }
+ nanos = nanos * Pow(10, static_cast<int>(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<int32_t>(nanos));
+ return true;
+}
+
+Duration TimeUtil::NanosecondsToDuration(int64_t nanos) {
+ return CreateNormalized<Duration>(nanos / kNanosPerSecond,
+ nanos % kNanosPerSecond);
+}
+
+Duration TimeUtil::MicrosecondsToDuration(int64_t micros) {
+ return CreateNormalized<Duration>(
+ micros / kMicrosPerSecond,
+ (micros % kMicrosPerSecond) * kNanosPerMicrosecond);
+}
+
+Duration TimeUtil::MillisecondsToDuration(int64_t millis) {
+ return CreateNormalized<Duration>(
+ millis / kMillisPerSecond,
+ (millis % kMillisPerSecond) * kNanosPerMillisecond);
+}
+
+Duration TimeUtil::SecondsToDuration(int64_t seconds) {
+ return CreateNormalized<Duration>(seconds, 0);
+}
+
+Duration TimeUtil::MinutesToDuration(int64_t minutes) {
+ return CreateNormalized<Duration>(minutes * kSecondsPerMinute, 0);
+}
+
+Duration TimeUtil::HoursToDuration(int64_t hours) {
+ return CreateNormalized<Duration>(hours * kSecondsPerHour, 0);
+}
+
+int64_t TimeUtil::DurationToNanoseconds(const Duration& duration) {
+ return duration.seconds() * kNanosPerSecond + duration.nanos();
+}
+
+int64_t TimeUtil::DurationToMicroseconds(const Duration& duration) {
+ return duration.seconds() * kMicrosPerSecond +
+ RoundTowardZero(duration.nanos(), kNanosPerMicrosecond);
+}
+
+int64_t TimeUtil::DurationToMilliseconds(const Duration& duration) {
+ return duration.seconds() * kMillisPerSecond +
+ RoundTowardZero(duration.nanos(), kNanosPerMillisecond);
+}
+
+int64_t TimeUtil::DurationToSeconds(const Duration& duration) {
+ return duration.seconds();
+}
+
+int64_t TimeUtil::DurationToMinutes(const Duration& duration) {
+ return RoundTowardZero(duration.seconds(), kSecondsPerMinute);
+}
+
+int64_t TimeUtil::DurationToHours(const Duration& duration) {
+ return RoundTowardZero(duration.seconds(), kSecondsPerHour);
+}
+
+Timestamp TimeUtil::NanosecondsToTimestamp(int64_t nanos) {
+ return CreateNormalized<Timestamp>(nanos / kNanosPerSecond,
+ nanos % kNanosPerSecond);
+}
+
+Timestamp TimeUtil::MicrosecondsToTimestamp(int64_t micros) {
+ return CreateNormalized<Timestamp>(
+ micros / kMicrosPerSecond,
+ micros % kMicrosPerSecond * kNanosPerMicrosecond);
+}
+
+Timestamp TimeUtil::MillisecondsToTimestamp(int64_t millis) {
+ return CreateNormalized<Timestamp>(
+ millis / kMillisPerSecond,
+ millis % kMillisPerSecond * kNanosPerMillisecond);
+}
+
+Timestamp TimeUtil::SecondsToTimestamp(int64_t seconds) {
+ return CreateNormalized<Timestamp>(seconds, 0);
+}
+
+int64_t TimeUtil::TimestampToNanoseconds(const Timestamp& timestamp) {
+ return timestamp.seconds() * kNanosPerSecond + timestamp.nanos();
+}
+
+int64_t TimeUtil::TimestampToMicroseconds(const Timestamp& timestamp) {
+ return timestamp.seconds() * kMicrosPerSecond +
+ RoundTowardZero(timestamp.nanos(), kNanosPerMicrosecond);
+}
+
+int64_t TimeUtil::TimestampToMilliseconds(const Timestamp& timestamp) {
+ return timestamp.seconds() * kMillisPerSecond +
+ RoundTowardZero(timestamp.nanos(), kNanosPerMillisecond);
+}
+
+int64_t TimeUtil::TimestampToSeconds(const Timestamp& timestamp) {
+ return timestamp.seconds();
+}
+
+Timestamp TimeUtil::TimeTToTimestamp(time_t value) {
+ return CreateNormalized<Timestamp>(static_cast<int64_t>(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<uint64_t>(-value.seconds());
+ *result = *result * kNanosPerSecond + static_cast<uint32_t>(-value.nanos());
+ } else {
+ *negative = false;
+ *result = static_cast<uint64_t>(value.seconds());
+ *result = *result * kNanosPerSecond + static_cast<uint32_t>(value.nanos());
+ }
+}
+
+void ToDuration(const uint128& value, bool negative, Duration* duration) {
+ int64_t seconds =
+ static_cast<int64_t>(Uint128Low64(value / kNanosPerSecond));
+ int32_t nanos =
+ static_cast<int32_t>(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, int64_t r) { // NOLINT
+ bool negative;
+ uint128 value;
+ ToUint128(d, &value, &negative);
+ if (r > 0) {
+ value *= static_cast<uint64_t>(r);
+ } else {
+ negative = !negative;
+ value *= static_cast<uint64_t>(-r);
+ }
+ ToDuration(value, negative, &d);
+ return d;
+}
+
+Duration& operator*=(Duration& d, double r) { // NOLINT
+ double result =
+ (static_cast<double>(d.seconds()) + d.nanos() * (1.0 / kNanosPerSecond)) *
+ r;
+ int64_t seconds = static_cast<int64_t>(result);
+ int32_t nanos = static_cast<int32_t>((result - static_cast<double>(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, int64_t r) { // NOLINT
+ bool negative;
+ uint128 value;
+ ToUint128(d, &value, &negative);
+ if (r > 0) {
+ value /= static_cast<uint64_t>(r);
+ } else {
+ negative = !negative;
+ value /= static_cast<uint64_t>(-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;
+}
+
+int64_t operator/(const Duration& d1, const Duration& d2) {
+ bool negative1, negative2;
+ uint128 value1, value2;
+ ToUint128(d1, &value1, &negative1);
+ ToUint128(d2, &value2, &negative2);
+ int64_t 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/toolkit/components/protobuf/src/google/protobuf/util/time_util.h b/toolkit/components/protobuf/src/google/protobuf/util/time_util.h
new file mode 100644
index 0000000000..709527ea27
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/time_util.h
@@ -0,0 +1,314 @@
+// 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_t tv_sec; /* seconds */
+ int64_t 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>
+
+// Must be included last.
+#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 int64_t kTimestampMinSeconds = -62135596800LL;
+ // For "9999-12-31T23:59:59.999999999Z".
+ static const int64_t kTimestampMaxSeconds = 253402300799LL;
+ static const int64_t kDurationMinSeconds = -315576000000LL;
+ static const int64_t 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 std::string ToString(const Timestamp& timestamp);
+ static bool FromString(const std::string& 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 std::string ToString(const Duration& duration);
+ static bool FromString(const std::string& 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(int64_t nanos);
+ static Duration MicrosecondsToDuration(int64_t micros);
+ static Duration MillisecondsToDuration(int64_t millis);
+ static Duration SecondsToDuration(int64_t seconds);
+ static Duration MinutesToDuration(int64_t minutes);
+ static Duration HoursToDuration(int64_t 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 int64_t DurationToNanoseconds(const Duration& duration);
+ static int64_t DurationToMicroseconds(const Duration& duration);
+ static int64_t DurationToMilliseconds(const Duration& duration);
+ static int64_t DurationToSeconds(const Duration& duration);
+ static int64_t DurationToMinutes(const Duration& duration);
+ static int64_t 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(int64_t nanos);
+ static Timestamp MicrosecondsToTimestamp(int64_t micros);
+ static Timestamp MillisecondsToTimestamp(int64_t millis);
+ static Timestamp SecondsToTimestamp(int64_t 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 int64_t TimestampToNanoseconds(const Timestamp& timestamp);
+ static int64_t TimestampToMicroseconds(const Timestamp& timestamp);
+ static int64_t TimestampToMilliseconds(const Timestamp& timestamp);
+ static int64_t 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, int64_t r); // NOLINT
+PROTOBUF_EXPORT Duration& operator*=(Duration& d, double r); // NOLINT
+PROTOBUF_EXPORT Duration& operator/=(Duration& d, int64_t 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
+ int64_t x = r;
+ return d *= x;
+}
+template <typename T>
+Duration& operator/=(Duration& d, T r) { // NOLINT
+ int64_t 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 int64_t 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/toolkit/components/protobuf/src/google/protobuf/util/type_resolver.h b/toolkit/components/protobuf/src/google/protobuf/util/type_resolver.h
new file mode 100644
index 0000000000..b2e7b43d76
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/type_resolver.h
@@ -0,0 +1,77 @@
+// 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>
+
+// Must be included last.
+#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 std::string& type_url, google::protobuf::Type* message_type) = 0;
+
+ // Resolves a type url for an enum type.
+ virtual util::Status ResolveEnumType(const std::string& 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/toolkit/components/protobuf/src/google/protobuf/util/type_resolver_util.cc b/toolkit/components/protobuf/src/google/protobuf/util/type_resolver_util.cc
new file mode 100644
index 0000000000..8be0efbe7b
--- /dev/null
+++ b/toolkit/components/protobuf/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/stubs/strutil.h>
+#include <google/protobuf/stubs/status.h>
+#include <google/protobuf/util/internal/utility.h>
+#include <google/protobuf/util/type_resolver.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 std::string& url_prefix,
+ const DescriptorPool* pool)
+ : url_prefix_(url_prefix), pool_(pool) {}
+
+ util::Status ResolveMessageType(const std::string& type_url,
+ Type* type) override {
+ std::string 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 std::string& type_url,
+ Enum* enum_type) override {
+ std::string 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 std::string& 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());
+ }
+
+ std::string GetTypeUrl(const Descriptor* descriptor) {
+ return url_prefix_ + "/" + descriptor->full_name();
+ }
+
+ std::string GetTypeUrl(const EnumDescriptor* descriptor) {
+ return url_prefix_ + "/" + descriptor->full_name();
+ }
+
+ util::Status ParseTypeUrl(const std::string& type_url,
+ std::string* 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();
+ }
+
+ std::string 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 "";
+ }
+
+ std::string url_prefix_;
+ const DescriptorPool* pool_;
+};
+
+} // namespace
+
+TypeResolver* NewTypeResolverForDescriptorPool(const std::string& url_prefix,
+ const DescriptorPool* pool) {
+ return new DescriptorPoolTypeResolver(url_prefix, pool);
+}
+
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/type_resolver_util.h b/toolkit/components/protobuf/src/google/protobuf/util/type_resolver_util.h
new file mode 100644
index 0000000000..7f6a4b9b11
--- /dev/null
+++ b/toolkit/components/protobuf/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>
+
+namespace google {
+namespace protobuf {
+class DescriptorPool;
+namespace util {
+class TypeResolver;
+
+// Must be included last.
+#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 std::string& 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/toolkit/components/protobuf/src/google/protobuf/wire_format.cc b/toolkit/components/protobuf/src/google/protobuf/wire_format.cc
new file mode 100644
index 0000000000..6fe63c86ce
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/wire_format.cc
@@ -0,0 +1,1768 @@
+// 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/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/descriptor.pb.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/parse_context.h>
+#include <google/protobuf/unknown_field_set.h>
+
+
+// Must be included last.
+#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,
+ uint32_t 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, uint32_t 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: {
+ uint64_t value;
+ if (!input->ReadVarint64(&value)) return false;
+ if (unknown_fields != nullptr) unknown_fields->AddVarint(number, value);
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_FIXED64: {
+ uint64_t value;
+ if (!input->ReadLittleEndian64(&value)) return false;
+ if (unknown_fields != nullptr) unknown_fields->AddFixed64(number, value);
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
+ uint32_t 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: {
+ uint32_t 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) {
+ uint32_t 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,
+ uint32_t field_number,
+ bool (*is_valid)(int),
+ UnknownFieldSet* unknown_fields,
+ RepeatedField<int>* values) {
+ uint32_t 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(int32_t);
+ break;
+ case UnknownField::TYPE_FIXED64:
+ size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag(
+ field.number(), WireFormatLite::WIRETYPE_FIXED64));
+ size += sizeof(int64_t);
+ 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) {
+ uint32_t 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,
+ uint32_t field_number,
+ UnknownFieldSet* unknown_fields) {
+ uint32_t length;
+ if (!input->ReadVarint32(&length)) return false;
+ return input->ReadString(unknown_fields->AddLengthDelimited(field_number),
+ length);
+}
+
+bool WireFormat::ParseAndMergeMessageSetField(uint32_t 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(
+ uint32_t 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) {
+ uint32_t 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, int32_t, Int32)
+ HANDLE_PACKED_TYPE(INT64, int64_t, Int64)
+ HANDLE_PACKED_TYPE(SINT32, int32_t, Int32)
+ HANDLE_PACKED_TYPE(SINT64, int64_t, Int64)
+ HANDLE_PACKED_TYPE(UINT32, uint32_t, UInt32)
+ HANDLE_PACKED_TYPE(UINT64, uint64_t, UInt64)
+
+ HANDLE_PACKED_TYPE(FIXED32, uint32_t, UInt32)
+ HANDLE_PACKED_TYPE(FIXED64, uint64_t, UInt64)
+ HANDLE_PACKED_TYPE(SFIXED32, int32_t, Int32)
+ HANDLE_PACKED_TYPE(SFIXED64, int64_t, 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.
+ int64_t sign_extended_value = static_cast<int64_t>(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, int32_t, Int32)
+ HANDLE_TYPE(INT64, int64_t, Int64)
+ HANDLE_TYPE(SINT32, int32_t, Int32)
+ HANDLE_TYPE(SINT64, int64_t, Int64)
+ HANDLE_TYPE(UINT32, uint32_t, UInt32)
+ HANDLE_TYPE(UINT64, uint64_t, UInt64)
+
+ HANDLE_TYPE(FIXED32, uint32_t, UInt32)
+ HANDLE_TYPE(FIXED64, uint64_t, UInt64)
+ HANDLE_TYPE(SFIXED32, int32_t, Int32)
+ HANDLE_TYPE(SFIXED64, int64_t, 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);
+ std::string 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: {
+ std::string 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(uint32_t 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);
+ enum class State { kNoTag, kHasType, kHasPayload, kDone };
+ State state = State::kNoTag;
+
+ std::string payload;
+ uint32_t type_id = 0;
+ while (!ctx->Done(&ptr)) {
+ // We use 64 bit tags in order to allow typeid's that span the whole
+ // range of 32 bit numbers.
+ uint32_t tag = static_cast<uint8_t>(*ptr++);
+ if (tag == WireFormatLite::kMessageSetTypeIdTag) {
+ uint64_t tmp;
+ ptr = ParseBigVarint(ptr, &tmp);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ if (state == State::kNoTag) {
+ type_id = tmp;
+ state = State::kHasType;
+ } else if (state == State::kHasPayload) {
+ type_id = tmp;
+ 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());
+ }
+ state = State::kDone;
+ }
+ continue;
+ } else if (tag == WireFormatLite::kMessageSetMessageTag) {
+ if (state == State::kNoTag) {
+ int32_t size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ ptr = ctx->ReadString(ptr, size, &payload);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ state = State::kHasPayload;
+ } else if (state == State::kHasType) {
+ // 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<uint64_t>(type_id) * 8 + 2, reflection,
+ field);
+ state = State::kDone;
+ } else {
+ int32_t size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ ptr = ctx->Skip(ptr, size);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ }
+ } 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<std::string*>(nullptr), ptr, ctx);
+ }
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ }
+ return ptr;
+ }
+
+ const char* ParseMessageSet(const char* ptr, internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ uint32_t 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)) {
+ uint32_t 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, uint64_t 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, int32_t, Int32)
+ HANDLE_PACKED_TYPE(INT64, int64_t, Int64)
+ HANDLE_PACKED_TYPE(SINT32, int32_t, SInt32)
+ HANDLE_PACKED_TYPE(SINT64, int64_t, SInt64)
+ HANDLE_PACKED_TYPE(UINT32, uint32_t, UInt32)
+ HANDLE_PACKED_TYPE(UINT64, uint64_t, UInt64)
+
+ HANDLE_PACKED_TYPE(FIXED32, uint32_t, Fixed32)
+ HANDLE_PACKED_TYPE(FIXED64, uint64_t, Fixed64)
+ HANDLE_PACKED_TYPE(SFIXED32, int32_t, SFixed32)
+ HANDLE_PACKED_TYPE(SFIXED64, int64_t, 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](uint64_t 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, uint64_t, Bool)
+ HANDLE_TYPE(INT32, uint32_t, Int32)
+ HANDLE_TYPE(INT64, uint64_t, Int64)
+ HANDLE_TYPE(UINT32, uint32_t, UInt32)
+ HANDLE_TYPE(UINT64, uint64_t, UInt64)
+
+ case FieldDescriptor::TYPE_SINT32: {
+ int32_t 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: {
+ int64_t 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, uint32_t, UInt32)
+ HANDLE_TYPE(FIXED64, uint64_t, UInt64)
+ HANDLE_TYPE(SFIXED32, int32_t, Int32)
+ HANDLE_TYPE(SFIXED64, int64_t, Int64)
+
+ HANDLE_TYPE(FLOAT, float, Float)
+ HANDLE_TYPE(DOUBLE, double, Double)
+
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::TYPE_ENUM: {
+ uint32_t 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;
+ std::string 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: {
+ auto& msg = value.GetMessageValue();
+ target = WireFormatLite::InternalWriteMessage(2, msg, msg.GetCachedSize(),
+ 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, int32_t, Int32, Int32)
+ HANDLE_PRIMITIVE_TYPE(INT64, int64_t, Int64, Int64)
+ HANDLE_PRIMITIVE_TYPE(SINT32, int32_t, SInt32, Int32)
+ HANDLE_PRIMITIVE_TYPE(SINT64, int64_t, SInt64, Int64)
+ HANDLE_PRIMITIVE_TYPE(UINT32, uint32_t, UInt32, UInt32)
+ HANDLE_PRIMITIVE_TYPE(UINT64, uint64_t, 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, uint32_t, Fixed32, UInt32)
+ HANDLE_PRIMITIVE_TYPE(FIXED64, uint64_t, Fixed64, UInt64)
+ HANDLE_PRIMITIVE_TYPE(SFIXED32, int32_t, SFixed32, Int32)
+ HANDLE_PRIMITIVE_TYPE(SFIXED64, int64_t, 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;
+ }
+
+ auto get_message_from_field = [&message, &map_entries, message_reflection](
+ const FieldDescriptor* field, int j) {
+ if (!field->is_repeated()) {
+ return &message_reflection->GetMessage(message, field);
+ }
+ if (!map_entries.empty()) {
+ return map_entries[j];
+ }
+ return &message_reflection->GetRepeatedMessage(message, field, j);
+ };
+ 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, int32_t, Int32, Int32)
+ HANDLE_PRIMITIVE_TYPE(INT64, int64_t, Int64, Int64)
+ HANDLE_PRIMITIVE_TYPE(SINT32, int32_t, SInt32, Int32)
+ HANDLE_PRIMITIVE_TYPE(SINT64, int64_t, SInt64, Int64)
+ HANDLE_PRIMITIVE_TYPE(UINT32, uint32_t, UInt32, UInt32)
+ HANDLE_PRIMITIVE_TYPE(UINT64, uint64_t, UInt64, UInt64)
+
+ HANDLE_PRIMITIVE_TYPE(FIXED32, uint32_t, Fixed32, UInt32)
+ HANDLE_PRIMITIVE_TYPE(FIXED64, uint64_t, Fixed64, UInt64)
+ HANDLE_PRIMITIVE_TYPE(SFIXED32, int32_t, SFixed32, Int32)
+ HANDLE_PRIMITIVE_TYPE(SFIXED64, int64_t, 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
+
+ case FieldDescriptor::TYPE_GROUP: {
+ auto* msg = get_message_from_field(field, j);
+ target = WireFormatLite::InternalWriteGroup(field->number(), *msg,
+ target, stream);
+ } break;
+
+ case FieldDescriptor::TYPE_MESSAGE: {
+ auto* msg = get_message_from_field(field, j);
+ target = WireFormatLite::InternalWriteMessage(
+ field->number(), *msg, msg->GetCachedSize(), target, stream);
+ } break;
+
+ 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);
+ std::string scratch;
+ const std::string& 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: {
+ std::string scratch;
+ const std::string& 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.
+ auto& msg = message_reflection->GetMessage(message, field);
+ target = WireFormatLite::InternalWriteMessage(
+ WireFormatLite::kMessageSetMessageNumber, msg, msg.GetCachedSize(),
+ 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++) {
+ std::string scratch;
+ const std::string& 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/toolkit/components/protobuf/src/google/protobuf/wire_format.h b/toolkit/components/protobuf/src/google/protobuf/wire_format.h
new file mode 100644
index 0000000000..1acbf9e1f0
--- /dev/null
+++ b/toolkit/components/protobuf/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 <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/stubs/casts.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/parse_context.h>
+#include <google/protobuf/wire_format_lite.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+// Must be included last.
+#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, uint32_t 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,
+ uint32_t 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 uint32_t MakeTag(const FieldDescriptor* field);
+
+ // Parse a single field. The input should start out positioned immediately
+ // after the tag.
+ static bool ParseAndMergeField(
+ uint32_t 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,
+ uint32_t field_number,
+ UnknownFieldSet* unknown_fields);
+
+ // Parse a MessageSet field.
+ static bool ParseAndMergeMessageSetField(uint32_t 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,
+ uint64_t 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, uint32_t 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 uint32_t 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/toolkit/components/protobuf/src/google/protobuf/wire_format_lite.cc b/toolkit/components/protobuf/src/google/protobuf/wire_format_lite.cc
new file mode 100644
index 0000000000..5ab1ca16c6
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/wire_format_lite.cc
@@ -0,0 +1,818 @@
+// 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/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/stubs/stringprintf.h>
+
+
+// Must be included last.
+#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, uint32_t tag) {
+ // Field number 0 is illegal.
+ if (WireFormatLite::GetTagFieldNumber(tag) == 0) return false;
+ switch (WireFormatLite::GetTagWireType(tag)) {
+ case WireFormatLite::WIRETYPE_VARINT: {
+ uint64_t value;
+ if (!input->ReadVarint64(&value)) return false;
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_FIXED64: {
+ uint64_t value;
+ if (!input->ReadLittleEndian64(&value)) return false;
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
+ uint32_t 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: {
+ uint32_t value;
+ if (!input->ReadLittleEndian32(&value)) return false;
+ return true;
+ }
+ default: {
+ return false;
+ }
+ }
+}
+
+bool WireFormatLite::SkipField(io::CodedInputStream* input, uint32_t tag,
+ io::CodedOutputStream* output) {
+ // Field number 0 is illegal.
+ if (WireFormatLite::GetTagFieldNumber(tag) == 0) return false;
+ switch (WireFormatLite::GetTagWireType(tag)) {
+ case WireFormatLite::WIRETYPE_VARINT: {
+ uint64_t value;
+ if (!input->ReadVarint64(&value)) return false;
+ output->WriteVarint32(tag);
+ output->WriteVarint64(value);
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_FIXED64: {
+ uint64_t value;
+ if (!input->ReadLittleEndian64(&value)) return false;
+ output->WriteVarint32(tag);
+ output->WriteLittleEndian64(value);
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
+ uint32_t length;
+ if (!input->ReadVarint32(&length)) return false;
+ output->WriteVarint32(tag);
+ output->WriteVarint32(length);
+ // TODO(mkilavuz): Provide API to prevent extra string copying.
+ std::string 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: {
+ uint32_t 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) {
+ uint32_t 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) {
+ uint32_t 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, uint32_t 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,
+ uint32_t 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) {
+ uint32_t 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 {
+ uint32_t 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(uint32_t v, uint8_t* dest) {
+ WireFormatLite::WriteFixed32NoTagToArray(v, dest);
+}
+
+void EncodeFixedSizeValue(uint64_t v, uint8_t* dest) {
+ WireFormatLite::WriteFixed64NoTagToArray(v, dest);
+}
+
+void EncodeFixedSizeValue(int32_t v, uint8_t* dest) {
+ WireFormatLite::WriteSFixed32NoTagToArray(v, dest);
+}
+
+void EncodeFixedSizeValue(int64_t 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 uint32_t* a, int n,
+ io::CodedOutputStream* output) {
+ WriteArray<uint32_t>(a, n, output);
+}
+
+void WireFormatLite::WriteFixed64Array(const uint64_t* a, int n,
+ io::CodedOutputStream* output) {
+ WriteArray<uint64_t>(a, n, output);
+}
+
+void WireFormatLite::WriteSFixed32Array(const int32_t* a, int n,
+ io::CodedOutputStream* output) {
+ WriteArray<int32_t>(a, n, output);
+}
+
+void WireFormatLite::WriteSFixed64Array(const int64_t* a, int n,
+ io::CodedOutputStream* output) {
+ WriteArray<int64_t>(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, int32_t value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteInt32NoTag(value, output);
+}
+void WireFormatLite::WriteInt64(int field_number, int64_t value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteInt64NoTag(value, output);
+}
+void WireFormatLite::WriteUInt32(int field_number, uint32_t value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteUInt32NoTag(value, output);
+}
+void WireFormatLite::WriteUInt64(int field_number, uint64_t value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteUInt64NoTag(value, output);
+}
+void WireFormatLite::WriteSInt32(int field_number, int32_t value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteSInt32NoTag(value, output);
+}
+void WireFormatLite::WriteSInt64(int field_number, int64_t value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteSInt64NoTag(value, output);
+}
+void WireFormatLite::WriteFixed32(int field_number, uint32_t value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_FIXED32, output);
+ WriteFixed32NoTag(value, output);
+}
+void WireFormatLite::WriteFixed64(int field_number, uint64_t value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_FIXED64, output);
+ WriteFixed64NoTag(value, output);
+}
+void WireFormatLite::WriteSFixed32(int field_number, int32_t value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_FIXED32, output);
+ WriteSFixed32NoTag(value, output);
+}
+void WireFormatLite::WriteSFixed64(int field_number, int64_t 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<int32_t>::max();
+
+void WireFormatLite::WriteString(int field_number, const std::string& 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 std::string& 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 std::string& 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 std::string& 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);
+}
+
+uint8_t* WireFormatLite::InternalWriteGroup(int field_number,
+ const MessageLite& value,
+ uint8_t* target,
+ io::EpsCopyOutputStream* stream) {
+ target = stream->EnsureSpace(target);
+ 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);
+}
+
+uint8_t* WireFormatLite::InternalWriteMessage(int field_number,
+ const MessageLite& value,
+ int cached_size, uint8_t* target,
+ io::EpsCopyOutputStream* stream) {
+ target = stream->EnsureSpace(target);
+ target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
+ target = io::CodedOutputStream::WriteVarint32ToArray(
+ static_cast<uint32_t>(cached_size), target);
+ return value._InternalSerialize(target, stream);
+}
+
+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, std::string* value);
+inline static bool ReadBytesToString(io::CodedInputStream* input,
+ std::string* value) {
+ uint32_t length;
+ return input->ReadVarint32(&length) && input->ReadString(value, length);
+}
+
+bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
+ std::string* value) {
+ return ReadBytesToString(input, value);
+}
+
+bool WireFormatLite::ReadBytes(io::CodedInputStream* input, std::string** p) {
+ if (*p == &GetEmptyStringAlreadyInited()) {
+ *p = new std::string();
+ }
+ return ReadBytesToString(input, *p);
+}
+
+void PrintUTF8ErrorLog(StringPiece message_name,
+ StringPiece field_name, const char* operation_str,
+ bool emit_stacktrace) {
+ std::string stacktrace;
+ (void)emit_stacktrace; // Parameter is used by Google-internal code.
+ std::string quoted_field_name = "";
+ if (!field_name.empty()) {
+ if (!message_name.empty()) {
+ quoted_field_name =
+ StrCat(" '", message_name, ".", field_name, "'");
+ } else {
+ quoted_field_name = StrCat(" '", field_name, "'");
+ }
+ }
+ std::string error_message =
+ StrCat("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);
+ GOOGLE_LOG(ERROR) << error_message;
+}
+
+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");
+ uint32_t sum = n;
+ uint32_t msb_sum = 0;
+ for (int i = 0; i < n; i++) {
+ uint32_t 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");
+ uint64_t sum = n;
+ for (int i = 0; i < n; i++) {
+ uint64_t 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.
+ uint64_t tmp = x >= (static_cast<uint64_t>(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<int32_t>& value) {
+ return VarintSize<false, true>(value.data(), value.size());
+}
+
+size_t WireFormatLite::UInt32Size(const RepeatedField<uint32_t>& value) {
+ return VarintSize<false, false>(value.data(), value.size());
+}
+
+size_t WireFormatLite::SInt32Size(const RepeatedField<int32_t>& 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<int32_t>& 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<uint32_t>& 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<int32_t>& 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<int64_t>& value) {
+ return VarintSize64<false>(value.data(), value.size());
+}
+
+size_t WireFormatLite::UInt64Size(const RepeatedField<uint64_t>& value) {
+ return VarintSize64<false>(value.data(), value.size());
+}
+
+size_t WireFormatLite::SInt64Size(const RepeatedField<int64_t>& value) {
+ return VarintSize64<true>(value.data(), value.size());
+}
+
+#else
+
+size_t WireFormatLite::Int64Size(const RepeatedField<int64_t>& 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<uint64_t>& 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<int64_t>& 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/toolkit/components/protobuf/src/google/protobuf/wire_format_lite.h b/toolkit/components/protobuf/src/google/protobuf/wire_format_lite.h
new file mode 100644
index 0000000000..80d396156f
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/wire_format_lite.h
@@ -0,0 +1,1908 @@
+// 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 <limits>
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/port.h>
+#include <google/protobuf/stubs/casts.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/repeated_field.h>
+
+// Do UTF-8 validation on string type in Debug build only
+#ifndef NDEBUG
+#define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+#endif
+
+// 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
+
+
+// Must be included last.
+#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 uint32_t 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 uint32_t MakeTag(int field_number, WireType type);
+ static WireType GetTagWireType(uint32_t tag);
+ static int GetTagFieldNumber(uint32_t 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, uint32_t 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, uint32_t 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<uint32_t>((static_cast<uint32_t>(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 uint32_t EncodeFloat(float value);
+ static float DecodeFloat(uint32_t value);
+ static uint64_t EncodeDouble(double value);
+ static double DecodeDouble(uint64_t 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 uint32_t ZigZagEncode32(int32_t n);
+ static int32_t ZigZagDecode32(uint32_t n);
+ static uint64_t ZigZagEncode64(int64_t n);
+ static int64_t ZigZagDecode64(uint64_t 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, uint32_t 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, uint32_t 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(..., std::string* value) requires an
+ // existing std::string.
+ static inline bool ReadString(io::CodedInputStream* input,
+ std::string* value);
+ // ReadString(..., std::string** p) is internal-only, and should only be
+ // called from generated code. It starts by setting *p to "new std::string" 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, std::string** p);
+ // Analogous to ReadString().
+ static bool ReadBytes(io::CodedInputStream* input, std::string* value);
+ static bool ReadBytes(io::CodedInputStream* input, std::string** 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(
+ int32_t value, io::CodedOutputStream* output);
+ PROTOBUF_NDEBUG_INLINE static void WriteInt64NoTag(
+ int64_t value, io::CodedOutputStream* output);
+ PROTOBUF_NDEBUG_INLINE static void WriteUInt32NoTag(
+ uint32_t value, io::CodedOutputStream* output);
+ PROTOBUF_NDEBUG_INLINE static void WriteUInt64NoTag(
+ uint64_t value, io::CodedOutputStream* output);
+ PROTOBUF_NDEBUG_INLINE static void WriteSInt32NoTag(
+ int32_t value, io::CodedOutputStream* output);
+ PROTOBUF_NDEBUG_INLINE static void WriteSInt64NoTag(
+ int64_t value, io::CodedOutputStream* output);
+ PROTOBUF_NDEBUG_INLINE static void WriteFixed32NoTag(
+ uint32_t value, io::CodedOutputStream* output);
+ PROTOBUF_NDEBUG_INLINE static void WriteFixed64NoTag(
+ uint64_t value, io::CodedOutputStream* output);
+ PROTOBUF_NDEBUG_INLINE static void WriteSFixed32NoTag(
+ int32_t value, io::CodedOutputStream* output);
+ PROTOBUF_NDEBUG_INLINE static void WriteSFixed64NoTag(
+ int64_t 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 uint32_t* a, int n,
+ io::CodedOutputStream* output);
+ static void WriteFixed64Array(const uint64_t* a, int n,
+ io::CodedOutputStream* output);
+ static void WriteSFixed32Array(const int32_t* a, int n,
+ io::CodedOutputStream* output);
+ static void WriteSFixed64Array(const int64_t* 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, int32_t value,
+ io::CodedOutputStream* output);
+ static void WriteInt64(int field_number, int64_t value,
+ io::CodedOutputStream* output);
+ static void WriteUInt32(int field_number, uint32_t value,
+ io::CodedOutputStream* output);
+ static void WriteUInt64(int field_number, uint64_t value,
+ io::CodedOutputStream* output);
+ static void WriteSInt32(int field_number, int32_t value,
+ io::CodedOutputStream* output);
+ static void WriteSInt64(int field_number, int64_t value,
+ io::CodedOutputStream* output);
+ static void WriteFixed32(int field_number, uint32_t value,
+ io::CodedOutputStream* output);
+ static void WriteFixed64(int field_number, uint64_t value,
+ io::CodedOutputStream* output);
+ static void WriteSFixed32(int field_number, int32_t value,
+ io::CodedOutputStream* output);
+ static void WriteSFixed64(int field_number, int64_t 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 std::string& value,
+ io::CodedOutputStream* output);
+ static void WriteBytes(int field_number, const std::string& value,
+ io::CodedOutputStream* output);
+ static void WriteStringMaybeAliased(int field_number,
+ const std::string& value,
+ io::CodedOutputStream* output);
+ static void WriteBytesMaybeAliased(int field_number, const std::string& 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(
+ int32_t value, uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64NoTagToArray(
+ int64_t value, uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32NoTagToArray(
+ uint32_t value, uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64NoTagToArray(
+ uint64_t value, uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32NoTagToArray(
+ int32_t value, uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64NoTagToArray(
+ int64_t value, uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32NoTagToArray(
+ uint32_t value, uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64NoTagToArray(
+ uint64_t value, uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32NoTagToArray(
+ int32_t value, uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64NoTagToArray(
+ int64_t 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<int32_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64NoTagToArray(
+ const RepeatedField<int64_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32NoTagToArray(
+ const RepeatedField<uint32_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64NoTagToArray(
+ const RepeatedField<uint64_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32NoTagToArray(
+ const RepeatedField<int32_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64NoTagToArray(
+ const RepeatedField<int64_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32NoTagToArray(
+ const RepeatedField<uint32_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64NoTagToArray(
+ const RepeatedField<uint64_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32NoTagToArray(
+ const RepeatedField<int32_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64NoTagToArray(
+ const RepeatedField<int64_t>& 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,
+ int32_t value,
+ uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64ToArray(int field_number,
+ int64_t value,
+ uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32ToArray(int field_number,
+ uint32_t value,
+ uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64ToArray(int field_number,
+ uint64_t value,
+ uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32ToArray(int field_number,
+ int32_t value,
+ uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64ToArray(int field_number,
+ int64_t value,
+ uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32ToArray(int field_number,
+ uint32_t value,
+ uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64ToArray(int field_number,
+ uint64_t value,
+ uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32ToArray(int field_number,
+ int32_t value,
+ uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64ToArray(int field_number,
+ int64_t 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<int32_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64ToArray(
+ int field_number, const RepeatedField<int64_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32ToArray(
+ int field_number, const RepeatedField<uint32_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64ToArray(
+ int field_number, const RepeatedField<uint64_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32ToArray(
+ int field_number, const RepeatedField<int32_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64ToArray(
+ int field_number, const RepeatedField<int64_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32ToArray(
+ int field_number, const RepeatedField<uint32_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64ToArray(
+ int field_number, const RepeatedField<uint64_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32ToArray(
+ int field_number, const RepeatedField<int32_t>& value, uint8_t* output);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64ToArray(
+ int field_number, const RepeatedField<int64_t>& 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 std::string& value, uint8_t* target);
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBytesToArray(
+ int field_number, const std::string& 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.
+ static uint8_t* InternalWriteGroup(int field_number, const MessageLite& value,
+ uint8_t* target,
+ io::EpsCopyOutputStream* stream);
+ static uint8_t* InternalWriteMessage(int field_number,
+ const MessageLite& value,
+ int cached_size, 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<uint32_t>(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<uint32_t>(field_number) << 3) +
+ io::CodedOutputStream::VarintSize32(size)),
+ io::CodedOutputStream::IsDefaultSerializationDeterministic());
+ return InternalWriteMessage(field_number, value, value.GetCachedSize(),
+ 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(int32_t value);
+ static inline size_t Int64Size(int64_t value);
+ static inline size_t UInt32Size(uint32_t value);
+ static inline size_t UInt64Size(uint64_t value);
+ static inline size_t SInt32Size(int32_t value);
+ static inline size_t SInt64Size(int64_t value);
+ static inline size_t EnumSize(int value);
+ static inline size_t Int32SizePlusOne(int32_t value);
+ static inline size_t Int64SizePlusOne(int64_t value);
+ static inline size_t UInt32SizePlusOne(uint32_t value);
+ static inline size_t UInt64SizePlusOne(uint64_t value);
+ static inline size_t SInt32SizePlusOne(int32_t value);
+ static inline size_t SInt64SizePlusOne(int64_t value);
+ static inline size_t EnumSizePlusOne(int value);
+
+ static size_t Int32Size(const RepeatedField<int32_t>& value);
+ static size_t Int64Size(const RepeatedField<int64_t>& value);
+ static size_t UInt32Size(const RepeatedField<uint32_t>& value);
+ static size_t UInt64Size(const RepeatedField<uint64_t>& value);
+ static size_t SInt32Size(const RepeatedField<int32_t>& value);
+ static size_t SInt64Size(const RepeatedField<int64_t>& 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 std::string& value);
+ static inline size_t BytesSize(const std::string& 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, uint32_t 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, uint32_t 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, uint32_t 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 uint32_t WireFormatLite::MakeTag(int field_number,
+ WireType type) {
+ return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type);
+}
+
+inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32_t tag) {
+ return static_cast<WireType>(tag & kTagTypeMask);
+}
+
+inline int WireFormatLite::GetTagFieldNumber(uint32_t 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<uint32_t>(field_number << kTagTypeBits));
+ if (type == TYPE_GROUP) {
+ // Groups have both a start and an end tag.
+ return result * 2;
+ } else {
+ return result;
+ }
+}
+
+inline uint32_t WireFormatLite::EncodeFloat(float value) {
+ return bit_cast<uint32_t>(value);
+}
+
+inline float WireFormatLite::DecodeFloat(uint32_t value) {
+ return bit_cast<float>(value);
+}
+
+inline uint64_t WireFormatLite::EncodeDouble(double value) {
+ return bit_cast<uint64_t>(value);
+}
+
+inline double WireFormatLite::DecodeDouble(uint64_t 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.
+//
+// int32_t -> uint32_t
+// -------------------------
+// 0 -> 0
+// -1 -> 1
+// 1 -> 2
+// -2 -> 3
+// ... -> ...
+// 2147483647 -> 4294967294
+// -2147483648 -> 4294967295
+//
+// >> encode >>
+// << decode <<
+
+inline uint32_t WireFormatLite::ZigZagEncode32(int32_t n) {
+ // Note: the right-shift must be arithmetic
+ // Note: left shift must be unsigned because of overflow
+ return (static_cast<uint32_t>(n) << 1) ^ static_cast<uint32_t>(n >> 31);
+}
+
+inline int32_t WireFormatLite::ZigZagDecode32(uint32_t n) {
+ // Note: Using unsigned types prevent undefined behavior
+ return static_cast<int32_t>((n >> 1) ^ (~(n & 1) + 1));
+}
+
+inline uint64_t WireFormatLite::ZigZagEncode64(int64_t n) {
+ // Note: the right-shift must be arithmetic
+ // Note: left shift must be unsigned because of overflow
+ return (static_cast<uint64_t>(n) << 1) ^ static_cast<uint64_t>(n >> 63);
+}
+
+inline int64_t WireFormatLite::ZigZagDecode64(uint64_t n) {
+ // Note: Using unsigned types prevent undefined behavior
+ return static_cast<int64_t>((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,
+ std::string* value) {
+ return ReadBytes(input, value);
+}
+
+inline bool WireFormatLite::ReadString(io::CodedInputStream* input,
+ std::string** p) {
+ return ReadBytes(input, p);
+}
+
+inline uint8_t* InternalSerializeUnknownMessageSetItemsToArray(
+ const std::string& 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 std::string& unknown_fields) {
+ return unknown_fields.size();
+}
+
+// Implementation details of ReadPrimitive.
+
+template <>
+inline bool WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_INT32>(
+ io::CodedInputStream* input, int32_t* value) {
+ uint32_t temp;
+ if (!input->ReadVarint32(&temp)) return false;
+ *value = static_cast<int32_t>(temp);
+ return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int64_t, WireFormatLite::TYPE_INT64>(
+ io::CodedInputStream* input, int64_t* value) {
+ uint64_t temp;
+ if (!input->ReadVarint64(&temp)) return false;
+ *value = static_cast<int64_t>(temp);
+ return true;
+}
+template <>
+inline bool
+WireFormatLite::ReadPrimitive<uint32_t, WireFormatLite::TYPE_UINT32>(
+ io::CodedInputStream* input, uint32_t* value) {
+ return input->ReadVarint32(value);
+}
+template <>
+inline bool
+WireFormatLite::ReadPrimitive<uint64_t, WireFormatLite::TYPE_UINT64>(
+ io::CodedInputStream* input, uint64_t* value) {
+ return input->ReadVarint64(value);
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_SINT32>(
+ io::CodedInputStream* input, int32_t* value) {
+ uint32_t temp;
+ if (!input->ReadVarint32(&temp)) return false;
+ *value = ZigZagDecode32(temp);
+ return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int64_t, WireFormatLite::TYPE_SINT64>(
+ io::CodedInputStream* input, int64_t* value) {
+ uint64_t temp;
+ if (!input->ReadVarint64(&temp)) return false;
+ *value = ZigZagDecode64(temp);
+ return true;
+}
+template <>
+inline bool
+WireFormatLite::ReadPrimitive<uint32_t, WireFormatLite::TYPE_FIXED32>(
+ io::CodedInputStream* input, uint32_t* value) {
+ return input->ReadLittleEndian32(value);
+}
+template <>
+inline bool
+WireFormatLite::ReadPrimitive<uint64_t, WireFormatLite::TYPE_FIXED64>(
+ io::CodedInputStream* input, uint64_t* value) {
+ return input->ReadLittleEndian64(value);
+}
+template <>
+inline bool
+WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_SFIXED32>(
+ io::CodedInputStream* input, int32_t* value) {
+ uint32_t temp;
+ if (!input->ReadLittleEndian32(&temp)) return false;
+ *value = static_cast<int32_t>(temp);
+ return true;
+}
+template <>
+inline bool
+WireFormatLite::ReadPrimitive<int64_t, WireFormatLite::TYPE_SFIXED64>(
+ io::CodedInputStream* input, int64_t* value) {
+ uint64_t temp;
+ if (!input->ReadLittleEndian64(&temp)) return false;
+ *value = static_cast<int64_t>(temp);
+ return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>(
+ io::CodedInputStream* input, float* value) {
+ uint32_t 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) {
+ uint64_t 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) {
+ uint64_t 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) {
+ uint32_t temp;
+ if (!input->ReadVarint32(&temp)) return false;
+ *value = static_cast<int>(temp);
+ return true;
+}
+
+template <>
+inline const uint8_t*
+WireFormatLite::ReadPrimitiveFromArray<uint32_t, WireFormatLite::TYPE_FIXED32>(
+ const uint8_t* buffer, uint32_t* value) {
+ return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value);
+}
+template <>
+inline const uint8_t*
+WireFormatLite::ReadPrimitiveFromArray<uint64_t, WireFormatLite::TYPE_FIXED64>(
+ const uint8_t* buffer, uint64_t* value) {
+ return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value);
+}
+template <>
+inline const uint8_t*
+WireFormatLite::ReadPrimitiveFromArray<int32_t, WireFormatLite::TYPE_SFIXED32>(
+ const uint8_t* buffer, int32_t* value) {
+ uint32_t temp;
+ buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
+ *value = static_cast<int32_t>(temp);
+ return buffer;
+}
+template <>
+inline const uint8_t*
+WireFormatLite::ReadPrimitiveFromArray<int64_t, WireFormatLite::TYPE_SFIXED64>(
+ const uint8_t* buffer, int64_t* value) {
+ uint64_t temp;
+ buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
+ *value = static_cast<int64_t>(temp);
+ return buffer;
+}
+template <>
+inline const uint8_t*
+WireFormatLite::ReadPrimitiveFromArray<float, WireFormatLite::TYPE_FLOAT>(
+ const uint8_t* buffer, float* value) {
+ uint32_t 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) {
+ uint64_t 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.
+ uint32_t 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, uint32_t 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, uint32_t tag, io::CodedInputStream* input, \
+ RepeatedField<CPPTYPE>* values) { \
+ return ReadRepeatedFixedSizePrimitive<CPPTYPE, \
+ WireFormatLite::DECLARED_TYPE>( \
+ tag_size, tag, input, values); \
+ }
+
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32_t, TYPE_FIXED32)
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64_t, TYPE_FIXED64)
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32_t, TYPE_SFIXED32)
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64_t, 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, uint32_t 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).
+ int64_t 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<int64_t>(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(uint32_t, TYPE_FIXED32)
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64_t, TYPE_FIXED64)
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32_t, TYPE_SFIXED32)
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64_t, 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(int32_t value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint32SignExtended(value);
+}
+inline void WireFormatLite::WriteInt64NoTag(int64_t value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint64(static_cast<uint64_t>(value));
+}
+inline void WireFormatLite::WriteUInt32NoTag(uint32_t value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint32(value);
+}
+inline void WireFormatLite::WriteUInt64NoTag(uint64_t value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint64(value);
+}
+inline void WireFormatLite::WriteSInt32NoTag(int32_t value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint32(ZigZagEncode32(value));
+}
+inline void WireFormatLite::WriteSInt64NoTag(int64_t value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint64(ZigZagEncode64(value));
+}
+inline void WireFormatLite::WriteFixed32NoTag(uint32_t value,
+ io::CodedOutputStream* output) {
+ output->WriteLittleEndian32(value);
+}
+inline void WireFormatLite::WriteFixed64NoTag(uint64_t value,
+ io::CodedOutputStream* output) {
+ output->WriteLittleEndian64(value);
+}
+inline void WireFormatLite::WriteSFixed32NoTag(int32_t value,
+ io::CodedOutputStream* output) {
+ output->WriteLittleEndian32(static_cast<uint32_t>(value));
+}
+inline void WireFormatLite::WriteSFixed64NoTag(int64_t value,
+ io::CodedOutputStream* output) {
+ output->WriteLittleEndian64(static_cast<uint64_t>(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(int32_t value,
+ uint8_t* target) {
+ return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteInt64NoTagToArray(int64_t value,
+ uint8_t* target) {
+ return io::CodedOutputStream::WriteVarint64ToArray(
+ static_cast<uint64_t>(value), target);
+}
+inline uint8_t* WireFormatLite::WriteUInt32NoTagToArray(uint32_t value,
+ uint8_t* target) {
+ return io::CodedOutputStream::WriteVarint32ToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteUInt64NoTagToArray(uint64_t value,
+ uint8_t* target) {
+ return io::CodedOutputStream::WriteVarint64ToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteSInt32NoTagToArray(int32_t value,
+ uint8_t* target) {
+ return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
+ target);
+}
+inline uint8_t* WireFormatLite::WriteSInt64NoTagToArray(int64_t value,
+ uint8_t* target) {
+ return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
+ target);
+}
+inline uint8_t* WireFormatLite::WriteFixed32NoTagToArray(uint32_t value,
+ uint8_t* target) {
+ return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteFixed64NoTagToArray(uint64_t value,
+ uint8_t* target) {
+ return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteSFixed32NoTagToArray(int32_t value,
+ uint8_t* target) {
+ return io::CodedOutputStream::WriteLittleEndian32ToArray(
+ static_cast<uint32_t>(value), target);
+}
+inline uint8_t* WireFormatLite::WriteSFixed64NoTagToArray(int64_t value,
+ uint8_t* target) {
+ return io::CodedOutputStream::WriteLittleEndian64ToArray(
+ static_cast<uint64_t>(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<int32_t>& value, uint8_t* target) {
+ return WritePrimitiveNoTagToArray(value, WriteInt32NoTagToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteInt64NoTagToArray(
+ const RepeatedField<int64_t>& value, uint8_t* target) {
+ return WritePrimitiveNoTagToArray(value, WriteInt64NoTagToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteUInt32NoTagToArray(
+ const RepeatedField<uint32_t>& value, uint8_t* target) {
+ return WritePrimitiveNoTagToArray(value, WriteUInt32NoTagToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteUInt64NoTagToArray(
+ const RepeatedField<uint64_t>& value, uint8_t* target) {
+ return WritePrimitiveNoTagToArray(value, WriteUInt64NoTagToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteSInt32NoTagToArray(
+ const RepeatedField<int32_t>& value, uint8_t* target) {
+ return WritePrimitiveNoTagToArray(value, WriteSInt32NoTagToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteSInt64NoTagToArray(
+ const RepeatedField<int64_t>& value, uint8_t* target) {
+ return WritePrimitiveNoTagToArray(value, WriteSInt64NoTagToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteFixed32NoTagToArray(
+ const RepeatedField<uint32_t>& value, uint8_t* target) {
+ return WriteFixedNoTagToArray(value, WriteFixed32NoTagToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteFixed64NoTagToArray(
+ const RepeatedField<uint64_t>& value, uint8_t* target) {
+ return WriteFixedNoTagToArray(value, WriteFixed64NoTagToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteSFixed32NoTagToArray(
+ const RepeatedField<int32_t>& value, uint8_t* target) {
+ return WriteFixedNoTagToArray(value, WriteSFixed32NoTagToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteSFixed64NoTagToArray(
+ const RepeatedField<int64_t>& 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,
+ int32_t value,
+ uint8_t* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteInt32NoTagToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteInt64ToArray(int field_number,
+ int64_t value,
+ uint8_t* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteInt64NoTagToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteUInt32ToArray(int field_number,
+ uint32_t value,
+ uint8_t* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteUInt32NoTagToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteUInt64ToArray(int field_number,
+ uint64_t value,
+ uint8_t* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteUInt64NoTagToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteSInt32ToArray(int field_number,
+ int32_t value,
+ uint8_t* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteSInt32NoTagToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteSInt64ToArray(int field_number,
+ int64_t value,
+ uint8_t* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteSInt64NoTagToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteFixed32ToArray(int field_number,
+ uint32_t value,
+ uint8_t* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
+ return WriteFixed32NoTagToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteFixed64ToArray(int field_number,
+ uint64_t value,
+ uint8_t* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
+ return WriteFixed64NoTagToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteSFixed32ToArray(int field_number,
+ int32_t value,
+ uint8_t* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
+ return WriteSFixed32NoTagToArray(value, target);
+}
+inline uint8_t* WireFormatLite::WriteSFixed64ToArray(int field_number,
+ int64_t 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<int32_t>& value, uint8_t* target) {
+ return WritePrimitiveToArray(field_number, value, WriteInt32ToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteInt64ToArray(
+ int field_number, const RepeatedField<int64_t>& value, uint8_t* target) {
+ return WritePrimitiveToArray(field_number, value, WriteInt64ToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteUInt32ToArray(
+ int field_number, const RepeatedField<uint32_t>& value, uint8_t* target) {
+ return WritePrimitiveToArray(field_number, value, WriteUInt32ToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteUInt64ToArray(
+ int field_number, const RepeatedField<uint64_t>& value, uint8_t* target) {
+ return WritePrimitiveToArray(field_number, value, WriteUInt64ToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteSInt32ToArray(
+ int field_number, const RepeatedField<int32_t>& value, uint8_t* target) {
+ return WritePrimitiveToArray(field_number, value, WriteSInt32ToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteSInt64ToArray(
+ int field_number, const RepeatedField<int64_t>& value, uint8_t* target) {
+ return WritePrimitiveToArray(field_number, value, WriteSInt64ToArray, target);
+}
+inline uint8_t* WireFormatLite::WriteFixed32ToArray(
+ int field_number, const RepeatedField<uint32_t>& value, uint8_t* target) {
+ return WritePrimitiveToArray(field_number, value, WriteFixed32ToArray,
+ target);
+}
+inline uint8_t* WireFormatLite::WriteFixed64ToArray(
+ int field_number, const RepeatedField<uint64_t>& value, uint8_t* target) {
+ return WritePrimitiveToArray(field_number, value, WriteFixed64ToArray,
+ target);
+}
+inline uint8_t* WireFormatLite::WriteSFixed32ToArray(
+ int field_number, const RepeatedField<int32_t>& value, uint8_t* target) {
+ return WritePrimitiveToArray(field_number, value, WriteSFixed32ToArray,
+ target);
+}
+inline uint8_t* WireFormatLite::WriteSFixed64ToArray(
+ int field_number, const RepeatedField<int64_t>& 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 std::string& 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 std::string& value,
+ uint8_t* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
+ return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
+}
+
+
+// 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<uint32_t>(
+ value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()),
+ target);
+ return value
+ .MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizesToArray(
+ target);
+}
+
+// ===================================================================
+
+inline size_t WireFormatLite::Int32Size(int32_t value) {
+ return io::CodedOutputStream::VarintSize32SignExtended(value);
+}
+inline size_t WireFormatLite::Int64Size(int64_t value) {
+ return io::CodedOutputStream::VarintSize64(static_cast<uint64_t>(value));
+}
+inline size_t WireFormatLite::UInt32Size(uint32_t value) {
+ return io::CodedOutputStream::VarintSize32(value);
+}
+inline size_t WireFormatLite::UInt64Size(uint64_t value) {
+ return io::CodedOutputStream::VarintSize64(value);
+}
+inline size_t WireFormatLite::SInt32Size(int32_t value) {
+ return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
+}
+inline size_t WireFormatLite::SInt64Size(int64_t value) {
+ return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
+}
+inline size_t WireFormatLite::EnumSize(int value) {
+ return io::CodedOutputStream::VarintSize32SignExtended(value);
+}
+inline size_t WireFormatLite::Int32SizePlusOne(int32_t value) {
+ return io::CodedOutputStream::VarintSize32SignExtendedPlusOne(value);
+}
+inline size_t WireFormatLite::Int64SizePlusOne(int64_t value) {
+ return io::CodedOutputStream::VarintSize64PlusOne(
+ static_cast<uint64_t>(value));
+}
+inline size_t WireFormatLite::UInt32SizePlusOne(uint32_t value) {
+ return io::CodedOutputStream::VarintSize32PlusOne(value);
+}
+inline size_t WireFormatLite::UInt64SizePlusOne(uint64_t value) {
+ return io::CodedOutputStream::VarintSize64PlusOne(value);
+}
+inline size_t WireFormatLite::SInt32SizePlusOne(int32_t value) {
+ return io::CodedOutputStream::VarintSize32PlusOne(ZigZagEncode32(value));
+}
+inline size_t WireFormatLite::SInt64SizePlusOne(int64_t 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 std::string& value) {
+ return LengthDelimitedSize(value.size());
+}
+inline size_t WireFormatLite::BytesSize(const std::string& 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 uint32_t
+ // 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<uint32_t>(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;
+
+ uint32_t 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.
+ std::string message_data;
+
+ enum class State { kNoTag, kHasType, kHasPayload, kDone };
+ State state = State::kNoTag;
+
+ while (true) {
+ const uint32_t tag = input->ReadTagNoLastTag();
+ if (tag == 0) return false;
+
+ switch (tag) {
+ case WireFormatLite::kMessageSetTypeIdTag: {
+ uint32_t type_id;
+ if (!input->ReadVarint32(&type_id)) return false;
+ if (state == State::kNoTag) {
+ last_type_id = type_id;
+ state = State::kHasType;
+ } else if (state == State::kHasPayload) {
+ // 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(type_id, &sub_input)) {
+ return false;
+ }
+ message_data.clear();
+ state = State::kDone;
+ }
+
+ break;
+ }
+
+ case WireFormatLite::kMessageSetMessageTag: {
+ if (state == State::kHasType) {
+ // Already saw type_id, so we can parse this directly.
+ if (!ms.ParseField(last_type_id, input)) {
+ return false;
+ }
+ state = State::kDone;
+ } else if (state == State::kNoTag) {
+ // We haven't seen a type_id yet. Append this data to message_data.
+ uint32_t length;
+ if (!input->ReadVarint32(&length)) return false;
+ if (static_cast<int32_t>(length) < 0) return false;
+ uint32_t size = static_cast<uint32_t>(
+ 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;
+ state = State::kHasPayload;
+ } else {
+ if (!ms.SkipField(tag, 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/toolkit/components/protobuf/src/google/protobuf/wrappers.pb.cc b/toolkit/components/protobuf/src/google/protobuf/wrappers.pb.cc
new file mode 100644
index 0000000000..40ba60a492
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/wrappers.pb.cc
@@ -0,0 +1,1979 @@
+// 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
+
+namespace _pb = ::PROTOBUF_NAMESPACE_ID;
+namespace _pbi = _pb::internal;
+
+PROTOBUF_NAMESPACE_OPEN
+PROTOBUF_CONSTEXPR DoubleValue::DoubleValue(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.value_)*/0
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct DoubleValueDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR DoubleValueDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~DoubleValueDefaultTypeInternal() {}
+ union {
+ DoubleValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 DoubleValueDefaultTypeInternal _DoubleValue_default_instance_;
+PROTOBUF_CONSTEXPR FloatValue::FloatValue(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.value_)*/0
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct FloatValueDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR FloatValueDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~FloatValueDefaultTypeInternal() {}
+ union {
+ FloatValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FloatValueDefaultTypeInternal _FloatValue_default_instance_;
+PROTOBUF_CONSTEXPR Int64Value::Int64Value(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.value_)*/int64_t{0}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct Int64ValueDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR Int64ValueDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~Int64ValueDefaultTypeInternal() {}
+ union {
+ Int64Value _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 Int64ValueDefaultTypeInternal _Int64Value_default_instance_;
+PROTOBUF_CONSTEXPR UInt64Value::UInt64Value(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.value_)*/uint64_t{0u}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct UInt64ValueDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR UInt64ValueDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~UInt64ValueDefaultTypeInternal() {}
+ union {
+ UInt64Value _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 UInt64ValueDefaultTypeInternal _UInt64Value_default_instance_;
+PROTOBUF_CONSTEXPR Int32Value::Int32Value(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.value_)*/0
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct Int32ValueDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR Int32ValueDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~Int32ValueDefaultTypeInternal() {}
+ union {
+ Int32Value _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 Int32ValueDefaultTypeInternal _Int32Value_default_instance_;
+PROTOBUF_CONSTEXPR UInt32Value::UInt32Value(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.value_)*/0u
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct UInt32ValueDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR UInt32ValueDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~UInt32ValueDefaultTypeInternal() {}
+ union {
+ UInt32Value _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 UInt32ValueDefaultTypeInternal _UInt32Value_default_instance_;
+PROTOBUF_CONSTEXPR BoolValue::BoolValue(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.value_)*/false
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct BoolValueDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR BoolValueDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~BoolValueDefaultTypeInternal() {}
+ union {
+ BoolValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 BoolValueDefaultTypeInternal _BoolValue_default_instance_;
+PROTOBUF_CONSTEXPR StringValue::StringValue(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.value_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct StringValueDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR StringValueDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~StringValueDefaultTypeInternal() {}
+ union {
+ StringValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 StringValueDefaultTypeInternal _StringValue_default_instance_;
+PROTOBUF_CONSTEXPR BytesValue::BytesValue(
+ ::_pbi::ConstantInitialized): _impl_{
+ /*decltype(_impl_.value_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
+ , /*decltype(_impl_._cached_size_)*/{}} {}
+struct BytesValueDefaultTypeInternal {
+ PROTOBUF_CONSTEXPR BytesValueDefaultTypeInternal()
+ : _instance(::_pbi::ConstantInitialized{}) {}
+ ~BytesValueDefaultTypeInternal() {}
+ union {
+ BytesValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 BytesValueDefaultTypeInternal _BytesValue_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[9];
+static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr;
+static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr;
+
+const uint32_t 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, _impl_.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, _impl_.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, _impl_.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, _impl_.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, _impl_.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, _impl_.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, _impl_.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, _impl_.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, _impl_.value_),
+};
+static const ::_pbi::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 const ::_pb::Message* const file_default_instances[] = {
+ &::PROTOBUF_NAMESPACE_ID::_DoubleValue_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_FloatValue_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_Int64Value_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_UInt64Value_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_Int32Value_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_UInt32Value_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_BoolValue_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_StringValue_default_instance_._instance,
+ &::PROTOBUF_NAMESPACE_ID::_BytesValue_default_instance_._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 ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once;
+const ::_pbi::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 ::_pbi::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_PRIORITY2 static ::_pbi::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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.DoubleValue)
+}
+DoubleValue::DoubleValue(const DoubleValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ DoubleValue* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _this->_impl_.value_ = from._impl_.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.DoubleValue)
+}
+
+inline void DoubleValue::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){0}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+DoubleValue::~DoubleValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.DoubleValue)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void DoubleValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void DoubleValue::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void DoubleValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.DoubleValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.value_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* DoubleValue::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // double value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 9)) {
+ _impl_.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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // double value = 1;
+ static_assert(sizeof(uint64_t) == sizeof(double), "Code assumes uint64_t and double are the same size.");
+ double tmp_value = this->_internal_value();
+ uint64_t raw_value;
+ memcpy(&raw_value, &tmp_value, sizeof(tmp_value));
+ if (raw_value != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteDoubleToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ // double value = 1;
+ static_assert(sizeof(uint64_t) == sizeof(double), "Code assumes uint64_t and double are the same size.");
+ double tmp_value = this->_internal_value();
+ uint64_t raw_value;
+ memcpy(&raw_value, &tmp_value, sizeof(tmp_value));
+ if (raw_value != 0) {
+ total_size += 1 + 8;
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DoubleValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ DoubleValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DoubleValue::GetClassData() const { return &_class_data_; }
+
+
+void DoubleValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<DoubleValue*>(&to_msg);
+ auto& from = static_cast<const DoubleValue&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DoubleValue)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ static_assert(sizeof(uint64_t) == sizeof(double), "Code assumes uint64_t and double are the same size.");
+ double tmp_value = from._internal_value();
+ uint64_t raw_value;
+ memcpy(&raw_value, &tmp_value, sizeof(tmp_value));
+ if (raw_value != 0) {
+ _this->_internal_set_value(from._internal_value());
+ }
+ _this->_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(_impl_.value_, other->_impl_.value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata DoubleValue::GetMetadata() const {
+ return ::_pbi::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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FloatValue)
+}
+FloatValue::FloatValue(const FloatValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ FloatValue* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _this->_impl_.value_ = from._impl_.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FloatValue)
+}
+
+inline void FloatValue::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){0}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+FloatValue::~FloatValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FloatValue)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void FloatValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void FloatValue::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void FloatValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FloatValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.value_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FloatValue::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // float value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 13)) {
+ _impl_.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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // float value = 1;
+ static_assert(sizeof(uint32_t) == sizeof(float), "Code assumes uint32_t and float are the same size.");
+ float tmp_value = this->_internal_value();
+ uint32_t raw_value;
+ memcpy(&raw_value, &tmp_value, sizeof(tmp_value));
+ if (raw_value != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteFloatToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ // float value = 1;
+ static_assert(sizeof(uint32_t) == sizeof(float), "Code assumes uint32_t and float are the same size.");
+ float tmp_value = this->_internal_value();
+ uint32_t raw_value;
+ memcpy(&raw_value, &tmp_value, sizeof(tmp_value));
+ if (raw_value != 0) {
+ total_size += 1 + 4;
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FloatValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ FloatValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FloatValue::GetClassData() const { return &_class_data_; }
+
+
+void FloatValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<FloatValue*>(&to_msg);
+ auto& from = static_cast<const FloatValue&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FloatValue)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ static_assert(sizeof(uint32_t) == sizeof(float), "Code assumes uint32_t and float are the same size.");
+ float tmp_value = from._internal_value();
+ uint32_t raw_value;
+ memcpy(&raw_value, &tmp_value, sizeof(tmp_value));
+ if (raw_value != 0) {
+ _this->_internal_set_value(from._internal_value());
+ }
+ _this->_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(_impl_.value_, other->_impl_.value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FloatValue::GetMetadata() const {
+ return ::_pbi::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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Int64Value)
+}
+Int64Value::Int64Value(const Int64Value& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Int64Value* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _this->_impl_.value_ = from._impl_.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Int64Value)
+}
+
+inline void Int64Value::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){int64_t{0}}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+Int64Value::~Int64Value() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Int64Value)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Int64Value::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void Int64Value::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void Int64Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Int64Value)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.value_ = int64_t{0};
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Int64Value::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // int64 value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _impl_.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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // int64 value = 1;
+ if (this->_internal_value() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteInt64ToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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 += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_value());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Int64Value::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Int64Value::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Int64Value::GetClassData() const { return &_class_data_; }
+
+
+void Int64Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Int64Value*>(&to_msg);
+ auto& from = static_cast<const Int64Value&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int64Value)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_value() != 0) {
+ _this->_internal_set_value(from._internal_value());
+ }
+ _this->_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(_impl_.value_, other->_impl_.value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Int64Value::GetMetadata() const {
+ return ::_pbi::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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.UInt64Value)
+}
+UInt64Value::UInt64Value(const UInt64Value& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ UInt64Value* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _this->_impl_.value_ = from._impl_.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.UInt64Value)
+}
+
+inline void UInt64Value::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){uint64_t{0u}}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+UInt64Value::~UInt64Value() {
+ // @@protoc_insertion_point(destructor:google.protobuf.UInt64Value)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void UInt64Value::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void UInt64Value::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void UInt64Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.UInt64Value)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.value_ = uint64_t{0u};
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* UInt64Value::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // uint64 value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _impl_.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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // uint64 value = 1;
+ if (this->_internal_value() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteUInt64ToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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 += ::_pbi::WireFormatLite::UInt64SizePlusOne(this->_internal_value());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UInt64Value::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ UInt64Value::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UInt64Value::GetClassData() const { return &_class_data_; }
+
+
+void UInt64Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<UInt64Value*>(&to_msg);
+ auto& from = static_cast<const UInt64Value&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt64Value)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_value() != 0) {
+ _this->_internal_set_value(from._internal_value());
+ }
+ _this->_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(_impl_.value_, other->_impl_.value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata UInt64Value::GetMetadata() const {
+ return ::_pbi::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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Int32Value)
+}
+Int32Value::Int32Value(const Int32Value& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ Int32Value* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _this->_impl_.value_ = from._impl_.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Int32Value)
+}
+
+inline void Int32Value::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){0}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+Int32Value::~Int32Value() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Int32Value)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void Int32Value::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void Int32Value::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void Int32Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Int32Value)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.value_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Int32Value::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // int32 value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _impl_.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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // int32 value = 1;
+ if (this->_internal_value() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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 += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_value());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Int32Value::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ Int32Value::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Int32Value::GetClassData() const { return &_class_data_; }
+
+
+void Int32Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<Int32Value*>(&to_msg);
+ auto& from = static_cast<const Int32Value&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int32Value)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_value() != 0) {
+ _this->_internal_set_value(from._internal_value());
+ }
+ _this->_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(_impl_.value_, other->_impl_.value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Int32Value::GetMetadata() const {
+ return ::_pbi::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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.UInt32Value)
+}
+UInt32Value::UInt32Value(const UInt32Value& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ UInt32Value* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _this->_impl_.value_ = from._impl_.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.UInt32Value)
+}
+
+inline void UInt32Value::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){0u}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+UInt32Value::~UInt32Value() {
+ // @@protoc_insertion_point(destructor:google.protobuf.UInt32Value)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void UInt32Value::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void UInt32Value::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void UInt32Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.UInt32Value)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.value_ = 0u;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* UInt32Value::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // uint32 value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _impl_.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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // uint32 value = 1;
+ if (this->_internal_value() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteUInt32ToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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 += ::_pbi::WireFormatLite::UInt32SizePlusOne(this->_internal_value());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UInt32Value::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ UInt32Value::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UInt32Value::GetClassData() const { return &_class_data_; }
+
+
+void UInt32Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<UInt32Value*>(&to_msg);
+ auto& from = static_cast<const UInt32Value&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt32Value)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_value() != 0) {
+ _this->_internal_set_value(from._internal_value());
+ }
+ _this->_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(_impl_.value_, other->_impl_.value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata UInt32Value::GetMetadata() const {
+ return ::_pbi::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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.BoolValue)
+}
+BoolValue::BoolValue(const BoolValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ BoolValue* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _this->_impl_.value_ = from._impl_.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.BoolValue)
+}
+
+inline void BoolValue::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){false}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+}
+
+BoolValue::~BoolValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.BoolValue)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void BoolValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void BoolValue::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void BoolValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.BoolValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.value_ = false;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* BoolValue::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // bool value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _impl_.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)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // bool value = 1;
+ if (this->_internal_value() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@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;
+
+ uint32_t 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, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData BoolValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ BoolValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*BoolValue::GetClassData() const { return &_class_data_; }
+
+
+void BoolValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<BoolValue*>(&to_msg);
+ auto& from = static_cast<const BoolValue&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BoolValue)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_value() != 0) {
+ _this->_internal_set_value(from._internal_value());
+ }
+ _this->_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(_impl_.value_, other->_impl_.value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata BoolValue::GetMetadata() const {
+ return ::_pbi::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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.StringValue)
+}
+StringValue::StringValue(const StringValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ StringValue* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_value().empty()) {
+ _this->_impl_.value_.Set(from._internal_value(),
+ _this->GetArenaForAllocation());
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.StringValue)
+}
+
+inline void StringValue::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+ _impl_.value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+StringValue::~StringValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.StringValue)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void StringValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.value_.Destroy();
+}
+
+void StringValue::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void StringValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.StringValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.value_.ClearToEmpty();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* StringValue::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.StringValue.value"));
+ } 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)
+ uint32_t 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 = ::_pbi::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;
+
+ uint32_t 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, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData StringValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ StringValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*StringValue::GetClassData() const { return &_class_data_; }
+
+
+void StringValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<StringValue*>(&to_msg);
+ auto& from = static_cast<const StringValue&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.StringValue)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (!from._internal_value().empty()) {
+ _this->_internal_set_value(from._internal_value());
+ }
+ _this->_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(
+ &_impl_.value_, lhs_arena,
+ &other->_impl_.value_, rhs_arena
+ );
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata StringValue::GetMetadata() const {
+ return ::_pbi::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(arena, is_message_owned);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.BytesValue)
+}
+BytesValue::BytesValue(const BytesValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ BytesValue* const _this = this; (void)_this;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){}
+ , /*decltype(_impl_._cached_size_)*/{}};
+
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _impl_.value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_value().empty()) {
+ _this->_impl_.value_.Set(from._internal_value(),
+ _this->GetArenaForAllocation());
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.BytesValue)
+}
+
+inline void BytesValue::SharedCtor(
+ ::_pb::Arena* arena, bool is_message_owned) {
+ (void)arena;
+ (void)is_message_owned;
+ new (&_impl_) Impl_{
+ decltype(_impl_.value_){}
+ , /*decltype(_impl_._cached_size_)*/{}
+ };
+ _impl_.value_.InitDefault();
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ _impl_.value_.Set("", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+BytesValue::~BytesValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.BytesValue)
+ if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
+ (void)arena;
+ return;
+ }
+ SharedDtor();
+}
+
+inline void BytesValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ _impl_.value_.Destroy();
+}
+
+void BytesValue::SetCachedSize(int size) const {
+ _impl_._cached_size_.Set(size);
+}
+
+void BytesValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.BytesValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _impl_.value_.ClearToEmpty();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* BytesValue::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::_pbi::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 = ::_pbi::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)
+ uint32_t 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 = ::_pbi::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;
+
+ uint32_t 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, &_impl_._cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData BytesValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
+ BytesValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*BytesValue::GetClassData() const { return &_class_data_; }
+
+
+void BytesValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
+ auto* const _this = static_cast<BytesValue*>(&to_msg);
+ auto& from = static_cast<const BytesValue&>(from_msg);
+ // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BytesValue)
+ GOOGLE_DCHECK_NE(&from, _this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (!from._internal_value().empty()) {
+ _this->_internal_set_value(from._internal_value());
+ }
+ _this->_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(
+ &_impl_.value_, lhs_arena,
+ &other->_impl_.value_, rhs_arena
+ );
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata BytesValue::GetMetadata() const {
+ return ::_pbi::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/toolkit/components/protobuf/src/google/protobuf/wrappers.pb.h b/toolkit/components/protobuf/src/google/protobuf/wrappers.pb.h
new file mode 100644
index 0000000000..cc42a8ba5c
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/wrappers.pb.h
@@ -0,0 +1,1741 @@
+// 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 < 3021000
+#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 3021006 < 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_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 uint32_t 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 PROTOBUF_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) {
+ DoubleValue::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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_;
+ struct Impl_ {
+ double value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ FloatValue::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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_;
+ struct Impl_ {
+ float value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ Int64Value::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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();
+ int64_t value() const;
+ void set_value(int64_t value);
+ private:
+ int64_t _internal_value() const;
+ void _internal_set_value(int64_t 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_;
+ struct Impl_ {
+ int64_t value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ UInt64Value::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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();
+ uint64_t value() const;
+ void set_value(uint64_t value);
+ private:
+ uint64_t _internal_value() const;
+ void _internal_set_value(uint64_t 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_;
+ struct Impl_ {
+ uint64_t value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ Int32Value::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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();
+ int32_t value() const;
+ void set_value(int32_t value);
+ private:
+ int32_t _internal_value() const;
+ void _internal_set_value(int32_t 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_;
+ struct Impl_ {
+ int32_t value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ UInt32Value::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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();
+ uint32_t value() const;
+ void set_value(uint32_t value);
+ private:
+ uint32_t _internal_value() const;
+ void _internal_set_value(uint32_t 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_;
+ struct Impl_ {
+ uint32_t value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ BoolValue::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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_;
+ struct Impl_ {
+ bool value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ StringValue::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& value() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_value(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_value();
+ PROTOBUF_NODISCARD std::string* release_value();
+ void set_allocated_value(std::string* value);
+ private:
+ const std::string& _internal_value() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_value(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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 PROTOBUF_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) {
+ BytesValue::MergeImpl(*this, from);
+ }
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
+ 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 _impl_._cached_size_.Get(); }
+
+ private:
+ void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
+ 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);
+ 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 std::string& value() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_value(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_value();
+ PROTOBUF_NODISCARD std::string* release_value();
+ void set_allocated_value(std::string* value);
+ private:
+ const std::string& _internal_value() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_value(const std::string& value);
+ std::string* _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_;
+ struct Impl_ {
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ };
+ union { Impl_ _impl_; };
+ 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() {
+ _impl_.value_ = 0;
+}
+inline double DoubleValue::_internal_value() const {
+ return _impl_.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) {
+
+ _impl_.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() {
+ _impl_.value_ = 0;
+}
+inline float FloatValue::_internal_value() const {
+ return _impl_.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) {
+
+ _impl_.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() {
+ _impl_.value_ = int64_t{0};
+}
+inline int64_t Int64Value::_internal_value() const {
+ return _impl_.value_;
+}
+inline int64_t Int64Value::value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Int64Value.value)
+ return _internal_value();
+}
+inline void Int64Value::_internal_set_value(int64_t value) {
+
+ _impl_.value_ = value;
+}
+inline void Int64Value::set_value(int64_t value) {
+ _internal_set_value(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Int64Value.value)
+}
+
+// -------------------------------------------------------------------
+
+// UInt64Value
+
+// uint64 value = 1;
+inline void UInt64Value::clear_value() {
+ _impl_.value_ = uint64_t{0u};
+}
+inline uint64_t UInt64Value::_internal_value() const {
+ return _impl_.value_;
+}
+inline uint64_t UInt64Value::value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UInt64Value.value)
+ return _internal_value();
+}
+inline void UInt64Value::_internal_set_value(uint64_t value) {
+
+ _impl_.value_ = value;
+}
+inline void UInt64Value::set_value(uint64_t value) {
+ _internal_set_value(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.UInt64Value.value)
+}
+
+// -------------------------------------------------------------------
+
+// Int32Value
+
+// int32 value = 1;
+inline void Int32Value::clear_value() {
+ _impl_.value_ = 0;
+}
+inline int32_t Int32Value::_internal_value() const {
+ return _impl_.value_;
+}
+inline int32_t Int32Value::value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Int32Value.value)
+ return _internal_value();
+}
+inline void Int32Value::_internal_set_value(int32_t value) {
+
+ _impl_.value_ = value;
+}
+inline void Int32Value::set_value(int32_t value) {
+ _internal_set_value(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Int32Value.value)
+}
+
+// -------------------------------------------------------------------
+
+// UInt32Value
+
+// uint32 value = 1;
+inline void UInt32Value::clear_value() {
+ _impl_.value_ = 0u;
+}
+inline uint32_t UInt32Value::_internal_value() const {
+ return _impl_.value_;
+}
+inline uint32_t UInt32Value::value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UInt32Value.value)
+ return _internal_value();
+}
+inline void UInt32Value::_internal_set_value(uint32_t value) {
+
+ _impl_.value_ = value;
+}
+inline void UInt32Value::set_value(uint32_t value) {
+ _internal_set_value(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.UInt32Value.value)
+}
+
+// -------------------------------------------------------------------
+
+// BoolValue
+
+// bool value = 1;
+inline void BoolValue::clear_value() {
+ _impl_.value_ = false;
+}
+inline bool BoolValue::_internal_value() const {
+ return _impl_.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) {
+
+ _impl_.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() {
+ _impl_.value_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.value_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.StringValue.value)
+}
+inline std::string* StringValue::mutable_value() {
+ std::string* _s = _internal_mutable_value();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.StringValue.value)
+ return _s;
+}
+inline const std::string& StringValue::_internal_value() const {
+ return _impl_.value_.Get();
+}
+inline void StringValue::_internal_set_value(const std::string& value) {
+
+ _impl_.value_.Set(value, GetArenaForAllocation());
+}
+inline std::string* StringValue::_internal_mutable_value() {
+
+ return _impl_.value_.Mutable(GetArenaForAllocation());
+}
+inline std::string* StringValue::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.StringValue.value)
+ return _impl_.value_.Release();
+}
+inline void StringValue::set_allocated_value(std::string* value) {
+ if (value != nullptr) {
+
+ } else {
+
+ }
+ _impl_.value_.SetAllocated(value, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.value_.IsDefault()) {
+ _impl_.value_.Set("", 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() {
+ _impl_.value_.ClearToEmpty();
+}
+inline const std::string& 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) {
+
+ _impl_.value_.SetBytes(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.BytesValue.value)
+}
+inline std::string* BytesValue::mutable_value() {
+ std::string* _s = _internal_mutable_value();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.BytesValue.value)
+ return _s;
+}
+inline const std::string& BytesValue::_internal_value() const {
+ return _impl_.value_.Get();
+}
+inline void BytesValue::_internal_set_value(const std::string& value) {
+
+ _impl_.value_.Set(value, GetArenaForAllocation());
+}
+inline std::string* BytesValue::_internal_mutable_value() {
+
+ return _impl_.value_.Mutable(GetArenaForAllocation());
+}
+inline std::string* BytesValue::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.BytesValue.value)
+ return _impl_.value_.Release();
+}
+inline void BytesValue::set_allocated_value(std::string* value) {
+ if (value != nullptr) {
+
+ } else {
+
+ }
+ _impl_.value_.SetAllocated(value, GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (_impl_.value_.IsDefault()) {
+ _impl_.value_.Set("", 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/toolkit/components/protobuf/src/google/protobuf/wrappers.proto b/toolkit/components/protobuf/src/google/protobuf/wrappers.proto
new file mode 100644
index 0000000000..d49dd53c8d
--- /dev/null
+++ b/toolkit/components/protobuf/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;
+}